python——面向对象

语法错误和异常
异常:程序运行的时候报出来的,xxxError
异常处理格式:
try:
    可能出现异常的代码
except:
     如果有异常执行的代码
finally:
     无论是否存在异常都会被执行的代码
情况一:
try:
   有可能产生多个异常
 except 异常类型1:
     print()
 except  异常类型2:
     print()
注意:如果是多个except,异常类型的顺序许哟啊注意,最大的Exception要放在后面
情况二:获取Exception的错误原因
 except Exception as err:
        print('Error',err)------》就是错误原因  [Error pop from empty list]
def func():
    try:
        a=int(input('请输入一个数字:'))
        b=int(input('请输入一个数字:'))
        f=input('请输入一个符号(+ - * /):')

        if f=='+':
            result=a+b

        elif f=='-':
            result=a-b

        elif f=='*':
            result=a*b

        elif f=='/':
            result=a/b

        else:
            print('输入的符号不正确')
        print(result)
        list=[]
        list.pop()
        with open(r'F:\mm','r')as rstream:
            container=rstream.read()
            print(container)

    except ZeroDivisionError:
        print('除数不可以为0')
    except ValueError:
        print('请输入数字')
    except Exception as err:
        print('Error',err)


func()




情况三:
try:
   有可能有异常的代码
except 类型1:
   pass
else:
   如果try中没有异常则进入的代码
注意:如果使用else则在try代码中不能出现return
情况四:
文件操作:fp=open()  fp.read()  fp.close()
数据库操作:close()
try:
     pass
except:
      pass
finally:
    无论是否异常都需要执行的代码
def func():
    rstream=None
    try:
        with open('book', encoding='utf-8')as rstream:
            print(rstream.read())
            return 1
        # rstream = open(r'F:\p\ww\book.txt', 'rb', encoding='UTF-8')
    except Exception as err:
        print(err)
        return 2
    finally:
        print('enter---------')
        if rstream:
            rstream.close()
        return 3
x=func()
print(x)

'''
抛出异常 raise
注册: 用户名必须是6位
'''
def register():
    username=input('输入用户名:')
    if len(username)<6 or len(username)>6:
        raise Exception('用户长度必须是6位')
    else:
        print('您的用户名是:{}'.format(username))
try:
    register()
except Exception as err:
    print(err)
else:
    print('chenggong ')

集合推导式:
与列表推导式相似 只是符号不同,在列表推导式的基础上添加了一个去除重复项的功能,用{}表示
llist=[1,2,3,4,1,34]
set={x for x in llist}
print(set)
'''
字典推导式(不是重点  了解即可)
用字典推导式  实现键值交换
'''
dict={'a':'S','b':'B','c':'C','c':'D'}
new_dict={value:key for key,value in dict.items()}
print(new_dict)
# {'S': 'a', 'B': 'b', 'D': 'c'}
'''
通过列表生成式(列表推导式),我们可以直接创建一个列表。
但是,受到内存限制,列表容量肯定是有限的
而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间
如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢
这样就不必创建完整的list,从而节省大量的空间。在python中,这种一边循环一边计算的机制,称为生成器
'''
'''
得到生成器的方式:
1、通过列表推导式得到生成器  符号是()
'''
g=(i*3 for i in range(10))
print(type(g))
# 通过调用__next__()方式得到元素
print(g.__next__())
print(g.__next__())
# <class 'generator'>
# 0
# 3
'''
2、系统方法:  next()
每调用一次next则会产生一个元素
'''
g=(i*3 for i in range(10))
print(type(g))
print(next(g))
# <class 'generator'>
# 0
'''
StopIteration  生成器本来就只可以产生10个 但是代码仍然要求接着产生 这时会报错
'''

定义生成器的方式二:借助函数完成
只要函数中出现了yield关键字,说明函数就不在是函数了,而变成了生成器了
步骤:
1、定义一个函数,并在函数中使用yield关键字
2、调用函数,接收调用的结果
3、得到的结果就是生成器
4、借助于next() ,next ()得到元素
next()相当于return 和break
'''
def func():
    n=0
    while True:
        n+=1
        yield  n
g=func()
print(type(g))
print(next(g))
print(next(g))
# <class 'generator'>
# 1
# 2

# 用生成器实现斐波那契数列
def fib(lenght):
    a,b=0,1
    while True:
        n=0
        if n<lenght:
            c=a+b

            a,b=b,a+b
            n=n+1
            yield c
g=fib(100)
生成器方法:
__next__():获取下一个元素
sendvalue():向每次生成器调用中传值  注意:第一次调用send(None)
def gen():
    i=0
    while i<5:
        temp=yield i
        print(temp)
        i+=1
    return '没有更多的数据'
g=gen()
print(g.send(None))
n1=g.send('呵呵')
print(n1)
'''
进程——》线程——》协程
'''
def task1(n):
    for i in range(n):
        print('正在搬第{}块砖'.format(i))
        yield
def task2(n):
    for i in range(n):
        print('正在听{}首歌'.format(i))
        yield
g1=task1(12)
g2=task2(3)
while True:
    try:
        g1.__next__()
        g2.__next__()
    except StopIteration:
        print('wrong')
        break
'''
可迭代对象:1、生成器  2、元组  列表  集合 字典  字符串 用isinstance进行判断
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象
迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问完结束
迭代器只能往前不会后退
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
可迭代的是不是肯定就是迭代器?
生成器是可迭代的,也是迭代器
list是可迭代的,但是不是迭代器——》变成迭代iter(iteration)
生成器和迭代器的关系:
生成器只是迭代器的一种
'''
from collections.abc import Iterable

list=[1,2,3,4,5,6]
if isinstance(list,Iterable):
    print('true')
else:
    print('false')
print('__________')
g=(x+1 for x in range(2))
if isinstance(g,Iterable):
    print('true')
else:
    print('false')

print('_______')
list=[1,2,3,4]
list1=iter(list)
print(next(list1))
print(next(list1))

'''
面向对象:
程序            现实中
对象:          具体的事物
类  对象  属性  方法
所有的类名要求首字母大写,多个单词使用驼峰式命名
class 类名(父类):
    属性  特征
    方法  动作
'''
'''
定义类和属性
'''
class Student:
    # 类属性
    name='hua'
    age=2
'''
使用类,创建对象
'''
xiaowei=Student()
xiaowei.age=12
Student.name='ruirui'
print(Student.name)
# 对象属性
# 对象对属性的寻找  先在自己空间找  没有后再去类中找
'''
类中的方法
种类:普通方法  类方法  静态方法   魔术方法
'''
'''
普通方法的格式:
   def 方法名(self,参数):
     pass
'''
class Phone:
    brand='xiaomi'
    price=3000
    type='note 8 pro'
    # phone类内部方法:call
    def call(self):
        print(self)
        for list in self.phone_list:
            print(list.items())

        print('正在打电话')
        print(self.note)
phone1=Phone()
phone1.note='我是phone1的note'
phone1.phone_list=[{'num1':'1234'},{'num2':'8907'}]
# print(phone1,'----------')
# print(phone1.brand)
phone1.call()

print('*'*20)
phone2=Phone()
phone2.note='我是phone2的note'
# print(phone2)
phone2.call()

'''
class Phone:
    # 魔术方法之一:__名字__()
    def call(self):
        # self是不断变化的
        print(self.price)
        # 不能保证每个self中都存在price
        print('----call')
p=Phone()
p.price=90
p.call()
'''


class Iphone:
    def __init__(self):
        print('--------init')
    def call(self):
        print('---------call')
i=Iphone()
'''
1、找有没有一块空间是Iphone
2、利用Iphone类,向内存申请一块'Phone'一样的空间
3、去IPhone中找有没有__init__,如果没有则直接将内存地址赋值给对象名
4、如果有__init__,则会进入init方法执行里面的动作,执行结束胡,将内存地址赋值给对象
'''
print('--------------------------------------')
class Person:
    name='张三'
    def __init__(self):
        self.name='张三'
        self.age=10
    def eat(self):
        print('{}正在吃饭'.format(self.name))
    def run(self):
        print('{},今年{}岁,正在跑步'.format(self.name,self.age))
p=Person()
p.name='梨子'
p.eat()
p1=Person()
p1.name='西红柿'
p1.run()
print('*'*20)
class Qperson:
    name='张三'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self,name):
        print('{}正在吃饭'.format(self.name))
    def run(self,name,age):
        print('{},今年{}岁,正在跑步'.format(self.name,self.age))
p=Qperson('lili',89)
p.eat('bing')


'''
类方法
特点:
1、定义需要以来装饰器@classmethod
2、类方法中的参数不是一个对象,而是一个类
3、类方法中只可以使用类属性
4、类方法只可以使用类属性
5、类方法中可否使用普通方法?  不能
类中方法的调用,需要通过self.方法名()调用
'''
'''
类方法作用:
因为只能访问类属性和类方法,所以可以在对象创建之前,如果需要完成一些动作
不依赖于对象
'''
class Dog:
    def __init__(self,nickname):
        self.nickname=nickname
    #     动态添加属性
    def run(self):
        # self  对象
        print('{}在院子里跑来跑去'.format(self.nickname))
    @classmethod
    def test(cls):
        # cls  class
        print(cls)
        print(cls.nickname)
d=Dog('nick')
print(d.nickname)
d.run()
d.test()



print('------------------------------------------------')
'''
_属性名:表示这是一个私有属性  不可以通过类或者对象直接进行修改
'''
class Person:
    _age=18
    def show(self):
        print('--------',self.age)
    @classmethod
    def update_age(cls):
        cls._age=20

        print('-------类方法')
    @classmethod
    def show_age(cls):
        print(cls._age)
Person.update_age()

Person.show_age()
# Person.age=Person.age+1
# print(Person.age)

print('-------------------------------------------')
'''
静态方法:类似类方法
1、需要装饰器@staticmethod
2、静态方法无需传递self、cls参数
3、只能访问类的属性和方法,对象的属性和方法无法使用
4、加载实际同类方法
总结:
类方法  静态方法
不同:
1、装饰器不同
2、类方法是有参数的,静态方法没有参数
相同:
1、只能访问类的属性和方法,对象的属性和方法是无法访问的
2、都可以通过类名调用访问
3、都可以在创建对象之前使用,因为是不依赖于对象
普通方法与二者的区别与联系:
不同:
1、没有装饰器
2、普通方法永远是要依赖对象,因为每个普通方法都有一个self
3、只有创建了对象才可以调用普通方法,否则无法使用
'''
class Iperson:
    _age=18
    def show(self):
        print('--------',self.age)
    @classmethod
    def update_age(cls):
        cls._age=20

        print('-------类方法')
    @classmethod
    def show_age(cls):
        print(cls._age)
    @staticmethod
    def test():
        print('----------静态方法')
        print(Iperson._age)
Iperson.update_age()
Iperson.test()

'''
魔术方法:
1、__init__
初始化魔术方法
触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
参数:至少有一个self,接收对象
返回值:无
作用:初始化对象的成员
注意:使用该方式初始化的成员都是直接写入对象中,类中无法具有
2、__new__
实例化魔术方法:给对象开辟地址空间
触发时机:在实例化时触发
参数:至少一个cls接收当前类
返回值:必须返回一个对象实例
作用:实例化对象
注意:实例化对象时Object类底层实现,其他类继承了Object的_new_才能实现实例化对象
没事别碰这个魔术方法:先触发__new__才会触发__init__
object.__new__(cls)
3、__call__
调用对象的魔术方法
触发时机:将对象当作函数调用时触发     对象()
参数:至少一个self接收对象,其余根据调用时参数决定
返回值:根据情况而定
作用:可以将复杂的步骤进行合并操作,较少调用的步骤,方便使用
注意:无
如果想让对象当作函数进行使用,需要重写__call__()方法
4、__del__


1.对象赋值:
  p=Person()
  p1=p
  说明p p1都指向同一个地址空间
2.删除地址的引用:
  del p1 删除p1对地址的引用
3.查看对地址的引用次数:
  import sys
  sys.getrefcount(p)
4.当一个空间没有了任何引用,默认执行__del__
  ref=0

'''
class Person:
    def __init__(self):
        print('----------------init')
        print(self)
    def __new__(cls, *args, **kwargs):
        # 向内存要空间
        print('-----------------new')
        # return object.__new__(cls,*args,**kwargs)
        result= object.__new__(cls, *args, **kwargs)
        # position=object.__new__(cls)
        print(result)
        return result
    def __call__(self, name):
        print('--------------------call')
        print('名字是',name)
p1=Person()
p1('nick')
# Person.__new__()

# -----------------new
# <__main__.Person object at 0x0000027BC9BBE1F0>
# ----------------init
# <__main__.Person object at 0x0000027BC9BBE1F0>
print('----------------')
import sys
class Iperson:
    def __init__(self,name):
        self.name=name
    def __del__(self):
        print('---------del----------')
ip=Iperson('hello')
ip1=ip
ip2=ip
print(ip1.name)
print(ip2.name)
print(sys.getrefcount(ip))
# getrefcount()获取指向该地址的指针个数
del ip1
# ip1.name='keleld'
# print(ip.name)
# print(ip2.name)
print(sys.getrefcount(ip))
n=3
n1=n
print(n1)


'''
__str__
触发时机:打印对象名,自动触发去调用__str__里面的内容
注意:一定要在__str__方法中添加return,return后面内容就是打印对象看到的内容
魔术方法就是一个类/对象中的方法,和普通方法唯一的不同是,普通方法需要调用,而魔术方法是在特定时刻自动爆发
'''
class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return '姓名是'+self.name+',年龄是:'+str(self.age)
p=Person('tom',12)
print(p)
# 单纯打印对象名称,出来的是一个地址,地址对于开发者来说没有太大意义
# 如果想在打印对象名的时候能够给开发者更过一些信息量
p1=Person('Jack',20)
print(p1)


'''
总结:魔术方法
重点:
__init__ 创建完空间后指行的第一个方法
 __str__
了解:
__new__  开辟空间
__del__  没有指针引用的时候会调用
__call__  想不想将对象当成函数用



class Student:

    def __init__(self,name,age):
        self.__name=name
        self.__age=age
        self.__score=59
    def setAge(self,age):
        # set是为了赋值
        if age>0 and age<120:
            self.__age=age
        else:
            print('beyond')
    def setName(self,name):
        if len(name)>6:
            print('名字长度超出范围')
        else:
            self.__name=name
    def getAge(self):
        return self.__age
    def __str__(self):
        return '姓名{},年龄{},你的分数是:{}'.format(self.__name,self.__age,self.__score)
s=Student('lily',12)
print(s)
print('--------')
print(s.getAge())
s.setAge(1223)
print(s)
s.setName('xiaopeng')
print(s)
print('------------------------------')
print(dir(Student))
print(dir(s))
print('==================')
print(s._Student__age)
#
# s.__score=90

# 私有化:
# 封装:1、私有化属性  2、定义公有set和get方法
# 好处:
# 1、隐藏属性不被外界随意修改
# 2、也可以修改,通过函数
#  def  setXXX(self,xxx)
#       筛选赋值的内容
#3、如果想获取具体的某一个属性:
# 使用get函数
# 私有属性  系统会自动改名字  所以不可以直接访问


 if age<100 and age>0:
            self.__age=age
        else:
            print('不在规定的范围内')




'''
继承  is  a   has  a
'''
'''
两个类:
公路(Road)
属性:公路名称  公路长度
车(Car)
属性:车名   时速
方法:1、求车名在那条公路上以多少的时速行驶了多长  get_time(self,road)
     2、初始化车属性信息__init__方法
     3、打印对象显示车的属性信息
'''
import random
class Road:
    def __init__(self,name,length):
        self.name=name
        self.length=length
class Car:
    def __init__(self,name,speed):
        self.name=name
        self.speed=speed
    def get_time(self,road):
        ran_time=random.randint(1,10)
        print('{}在{}公路上行驶速度为每小时{}'.format(self.name,road.name,self.speed))
    def show(self):
        print('车的名称{},车的时速{}'.format(self.name,self.speed))
c=Car('奔驰','60')
c.show()
print('--------------')
r=Road('五三街道','100')

c.get_time(r)


class Computer:
    def __init__(self,brand,type,color):
        self.brand=brand
        self.type=type
        self.color=color
    def online(self):
        print('正在使用电脑上网')
    def __str__(self):
        return  self.brand+'-----'+self.type+'-------'+self.color
class Book:
    def __init__(self,bname,author,number):
        self.bname=bname
        self.author=author
        self.number=number

    def __str__(self):
        return self.bname+'---'+self.author+'------'+self.number


class Student:
    def __init__(self,name,computer,book):
        self.name=name
        self.computer=computer
        self.books=[]
        self.books.append(book)

    def borrow_book(self, book):
        for book1 in self.books:
            if book1.bname==book.bname:
                print('已经借过了')
                break
        else:
            self.books.append(book)
            print('{}已经添加成功'.format(book.bname))

    def show_book(self):
        for book in self.books:
            print(book.bname)
    def __str__(self):
        return self.name+'---'+str(self.computer)+'------'+str(self.books)
c=Computer('mac pro','mac 2018','深灰色')
book=Book('盗墓笔记','南派三叔',10)
s=Student('songsong',c,book)
print(s)
book1=Book('西游记','吴承恩',8)
print(s.show_book())
s.borrow_book(book1)
print('----------')
s.show_book()
# 知识点:
# 1、has a
# 一个类中使用了另外一种自定义的类型
# 2、类型
# 系统类型:str、int、float、list、dict、tuple、set
# 自定义类型:算式自定义的类,都可以将其当成一种类型
# s=Student()
# s是Student类型的变量



# is a
# 继承: Student Employee Doctor——都属于人类
# 相同的代码——》代码冗余 ,可读性不高
# 将相同的代码进行提取——》Person类
# Student,Employee,Doctor——》继承Person


'''
特点:
1、如果类中不定义__init__,调用super class 的__init__
2、如果类继承父类也需要定义自己的__init__,就需要在当前类的__init__调用一下父类__init__
3、如何调用父类__init__
   super().__init__(参数):
   super(类名,对象).__init__(参数):
4、如果父类有eat()方法,子类也定义一个eat方法,默认搜索的原则:先找当前类,再去找父类
   s.eat()
   override:重写(覆盖)
   父类提供的方法不能满足子类的需求,就需要在子类中定义一个同名的方法
5、子类的方法中也可以调用父类的方法:
   super().方法名(参数)
'''
class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def eat(self):
        print(self.name+'正在吃饭....')
    def run(self):
        print(self.name+'正在跑步。。。。。')
class Student(Person):
    def __init__(self,name,age,clazz):
        print('------------Student init')
        super().__init__(name,age)
        self.clazz=clazz
    def study(self,course):
        print('{}正在学{}课程'.format(self.name,course))
    def eat(self,food):
        super().eat()
        print(self.name + '正在吃饭....,喜欢吃{}'.format(food))
#         调用父类的方法



class Employee(Person):
    def __init__(self,name,age,salary,born):
      super().__init__(name,age)
      self.salary=salary
      self.born=born


class Doctor(Person):
    def __init__(self,name,age,patient):
        super().__init__(name, age)
        self.patients=[]
        self.patients.append(patient)

    def show(self):
        for patient in self.patients:
            print(patient)


s=Student('jack',18,'一班')
e=Employee('tom',23,10000,11)
s.study('python')
s.eat()
print('-------------')
d=Doctor('lucy',20,'lumingming')
d.run()
d=Doctor('lucy',20,'lily')
d.show()


'''
编写一个简单的工资管理程序,系统可以管理以下四类人:工人(worker)、销售员(salesman)、经理(manager)
、销售经理(salesman)
所有的员工都具有员工号、姓名、工资等属性,有设置姓名、获取姓名、获取员工号,计算工资等方法。
1)工人:工人具有工作小时数和时薪的属性,工资计算方法为工作小时数*时薪
2)销售员:具有销售额和提成比例的属性,工资计算方法为销售额+提成比例
3)经理:具有固定月薪的属性,工资计算方法为固定月薪
4)销售经理:工资计算方法为销售额*提成比例+固定月薪
请根据以上要求设计合理的类,完成以下功能:
1)添加所有类型的人员
2)计算月薪
3)显示所有人工资情况

'''
class Person:
    def __init__(self,number,name,salary):
        self.number=number
        self.name=name
        self.salary=salary
    def setName(self,name):
        self.name=name
        return self.name
    def getName(self):
        return self.name
    def getNumber(self):
        return self.salary
    def getSalary(self):
        return self.salary
    def __str__(self):
        return '员工号:{},薪水:{},姓名:{}'.format(self.number,self.salary,self.name)


class Worker(Person):
    def __init__(self,number,name,salary,hour,per_hour):
        super().__init__(number,name,salary)
        self.hour=hour
        self.per_hour=per_hour
    def getSalary(self):
        money=self.hour*self.per_hour
        self.salary=self.salary+money
        return self.salary
class Salesman(Person):
    def __init__(self,number,name,salary,salemoney,percent):
        super().__init__(number,name,salary)
        self.salemoney=salemoney
        self.percent=percent
    def getSalary(self):
        money=self.percent*self.salemoney
        self.salary=self.salary+money
        return self.salary

w=Worker('001','king',2000,160,100)
print(w.getSalary())
print(w)
print('-----------')
s=Salesman('002','lucy',5000,50000,0.003)
print(s.getSalary())
print(s)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值