原创:叫我詹躲躲
起源:思否
链接:python面型对象编程进阶(继承、多态、私有化、异样捕捉、类属性和类办法)
致谢:感激求知教育提供的视频教程
1.单继承
## 封装,继承和多态## 1.封装1、满足把内容封装到某个中央,另一个中央去调用封装的内容2、应用初始化构造方法,或者应用self获取封装的内容## 2.继承子类继承父类的属性和内容
1.1单继承示例
class Animal: def eat(self): print('吃饭了') pass def drink(self): print('喝水了') passclass Dog(Animal): def wwj(self): ## 子类独有的实现 print('小狗汪汪叫') passclass Cat(Animal): def mmj(self): ## 子类独有的实现 print('小猫喵喵叫') passd1 = Dog()d1.eat()d2 = Cat()d2.eat()## 总结:所以对于面向对象的继承来说,能够极大的晋升效率,缩小反复代码
2.多继承
class Shenxian: def fly(self): print('神仙会飞') passclass Monkey: def chitao(self): print('猴子喜爱吃桃') passclass Sunwukong(Shenxian,Monkey): passswk = Sunwukong()swk.fly()swk.chitao()
2.1 留神办法重名:
## 多个父类存在雷同的办法,该调用哪一个class D(object): def eat(self): print('D.eat') passclass C(object): def eat(self): print('C.eat') passclass B(D): passclass A(B,C): passa = A()a.eatprint(A.__mro__) ##显示类的继承程序<class '__main__.A'>,<class '__main__.B'>,<class '__main__.D'>,<class '__main__.C'>,<class 'object'>## 执行程序应该是 去A外面查找,找第一个父类,A中没有的话,去B中查找,,B类中没有,C类中没有,去D类中查找;
2.2案例 简洁继承
class Grandfather(): def eat(self): print('吃的办法') pass passclass Father(Grandfather): passclass Son(Father): passson = Son()print(Son.__mro__)## <class '__main__.Son'>,## <class '__main__.Father'>,## <class '__main__.Grandfather'>,## <class 'object'>
2.3重写父类办法
class Grandfather(): def eat(self): print('吃的办法') pass passclass Father(Grandfather): ## 笼罩了父类的办法 def eat(self): print('爸爸常常吃海鲜') passclass Son(Father): passson = Son()print(Son.__mro__)## 定义跟父类雷同的办法,能够实现笼罩和重写父类的办法
2.4重写初始化办法
class Grandfather(): def __init__(self,name): self.name = name pass def eat(self): print('吃的办法') pass passclass Father(Grandfather): def __init__(self): pass ## 笼罩了父类的办法 def eat(self): print('爸爸常常吃海鲜') passclass Son(Father): passson = Son()print(Son.__mro__)
2.5调用父类初始化办法
class Father: def __init__(self,name): self.name = name pass ## 笼罩了父类的办法 def eat(self): print('爸爸常常吃海鲜') passclass Son(Father): def __init__(self,name): Father.__init__(self,name) ##调用父类的办法,能够具备name属性 ## 或者 ## super.__init__(name) ##也能够这样写 self.age = 90 ## 增加新的实例办法 self.sex = '男' pass passson = Son('hello')
2.6 调用父类的办法
class Father: def __init__(self,name): self.name = name pass ## 笼罩了父类的办法 def eat(self): print('父类的吃办法') passclass Son(Father): def __init__(self,name): Father.__init__(self,name) ##调用父类的办法,能够具备name属性 ## 或者 ## super.__init__(name) ##也能够这样写 self.age = 90 ## 增加新的实例办法 self.sex = '男' pass pass def __str__(self): print('{}'.format(self.name)) pass def eat(self): super().eat() ##调用父类的办法 print('子类的吃办法') passson = Son('詹躲躲')son.eat()## 父类的吃办法## 子类的吃办法
3 多态
同一种行为,对于不同子类【对象】有不同的实现形式
3.1 要想实现多态,必须有两个前提
1.继承:产生在父类和子类之间2.重写:子类重写父类的办法
3.1 案例演示
class Animal: ## 根本类 def say(self): print('动物类') pass passclass Duck(Animal): ## 子类 派生类 def say(self): print('鸭子类') pass passclass Dog(Animal): ## 子类 派生类 def say(self): print('小狗类') pass pass## duck1 = Duck()## duck1.say()## dog = Dog()## dog.say()def commonIvoke(obj): ## 对立调用 obj.say()## 循环对立调用listObj = [Duck(),Dog()]for item in listObj: commonIvoke(item)## 在定义时的类型跟调用时不一样的时候,称为多态。
3.2 多态的益处
1.减少程序的灵活性
2.减少程序的扩展性
4.类属性和实例属性
## 类属性:就是类对象领有的属性,它被所有类对象的实例对象所共有,类对象和实例对象能够拜访。## 实例属性:实例对象所领有的属性,只能通过实例对象拜访。class Student: ## 类属性 name = '叫我詹躲躲' def __init__(self,age): self.age = age pass passlm = Student(18)## 通过实例对象去拜访类属性print(lm.name)print(lm.age)## 通过类对象去拜访print(Student.name)print(Student.age)## 总结## 类属性:类对象和实例对象都能够拜访## 实例属性:只能由实例属性拜访## 所有的实例对象指向同一类对象## 实例对象去批改类属性 不能批改## 类对象能够批改类属性 能够批改
5.类属性和静态方法
## 装璜器@classmethodclass Person: country = 'china' ## 类办法 用classmethod润饰 @classmethod def get_country(cls): return cls.country ## 拜访类属性 pass @classmethod def change_country(cls): cls.country = 'America' pass## 通过类对象去援用print(Person.get_country())print(Person.change_country())print(Person.get_country())
5.1 静态方法
class Person: country = 'china' ## 类办法 用classmethod润饰 @classmethod def get_country(cls): return cls.country ## 拜访类属性 pass @classmethod def change_country(cls): cls.country = 'America' pass @staticmethod def get_data(): return Person.country pass## 通过类对象去援用print(Person.get_country())print(Person.change_country())print(Person.get_country())print(Person.get_data())
个别不会通过是实例对象去拜访静态方法
因为静态方法次要寄存逻辑办法,自身与类以及实例没有交互,也就是不会波及类中办法和属性的操作
依据资源可能无效的利用
5.2求零碎以后的工夫
import timeclass sys_time: def __init__(self,hour,min,second): self.hour = hour self.min =min self.second = second @staticmethod ## 独立的性能 def show_time(): return time.strftime('%H:%M:%S',time.localtime())print(sys_time.show_time())## 15:15:44
5.3 总结
1.类办法的第一个参数是类对象,cls进而去援用类对象的属性和办法
2.实例办法的第一个参数是实例属性,若存在雷同的实例属性或者办法,实例属性优先级最高
3.静态方法不须要额定的参数,若须要援用属性。,则能够通过类对象或者实例对象去援用即可,必须应用装璜器@staticmethod装璜
6.私有化
6.1 私有化属性
## 公有属性 以__结尾,申明为属性公有,不能在类的内部被应用或者间接拜访。class Person(object): def __init__(self): self.__name = '叫我詹躲躲' ## 私有化 self.age = '21' pass def __str__(self): return '{}的年龄是{}'.format(self.__name,self.age)person = Person()## print(person.__name) ##报错print(person) ##能够拜访## 叫我詹躲躲的年龄是21## 公有属性,不能被子类继承
6.2私有化办法
class A(object): def __eat(self): print('吃饭') pass pass def run(self): print('跑步') pass passb = A()b.__eat() ## 报错b.run() ## 跑步
7.property办法
属性函数
class A(object): def __init__(self): self.__name = 18 def __eat(self): return self.__name pass pass def run(self): print('跑步') pass pass age = property(__eat, run)b = A()print(b.age) ## 报错b.run() ## 跑步
7.1 @age.setter ##批改属性
class A(object): def __init__(self): self.__name = 18 def __eat(self): return self.__name pass pass def run(self): print('跑步') pass @property ##增加属性标识 def age(self): return self.__name pass @age.setter ##批改属性 def age(self,params): self.age = params pass passp1 = A()print(p1.age) ## 18p1.age = 16print(p1.age)
8. __new__办法
作用:创立并返回一个实例对象,如果__new__只调用了一次,就会失去一个对象。继承自object的旧式类,才有new这一魔术办法。
8.1 注意事项
1.__new__是一个实例化调用的第一个办法 2.__new__至多必须有一个参数 cls,代表要实例化的类,此参数在实例化时由python解释器提供,其余的参数是间接传递给__init__办法 3.__new__决定是否应用该__init__办法,因为__new__能够调用其余的类的构造方法或者返回实例对象作为类的实例,如果__new__没有返回实例,则__init__不会被调用 4.在__init__办法中,不能调用本人的__new__办法,return cls__new__(cls),否则会报错。
class A(object): def __init__(self): print('__init__执行了') pass pass def __new__(cls,*args,**kwargs): return super().__new__(cls,*args,**kwargs) pass passa = A()print(a)__init__执行了<__main__.A object at 0x00000291F97D5160>## 当__new__返回的时候 __init__才会显示
9.单例模式
9.1 确保一个类只有一个实例存在,应用__new__
class DataBaseClass(object): def __new__(cls,*args,**kwargs): ## cls._instance = cls.__new__(cls) ##不能应用本人的new办法 if not hasattr(cls,'_instance'): cls._instance = super().__new__(cls,*args,**kwargs) return cls._instance pass passdb1 = DataBaseClass()db2 = DataBaseClass()db3 = DataBaseClass()print(id(db1))print(id(db2))print(id(db3))## 三个指向的内存地址都一样的## 1852298514784## 1852298514784## 1852298514784
10 谬误和异样解决
try: ## 可能呈现谬误的代码块except: ## 出错之后执行的代码块else: ## 没有出错的代码块finally: ## 不论有没有出错,都会执行
10.1 谬误和异样解决示例
try: ## 可能呈现谬误的代码块 li = [1,2,3] ## print(li[10]) print(1/0)except IndexError as msg: ## 出错之后执行的代码块 print(msg)except ZeroDivisionError as msg: ## 出错之后执行的代码块 print(msg)else: ## 没有出错的代码块 print('没有出错了')finally: ## 不论有没有出错,都会执行 print('出错了')## 用一个try能够捕捉多个不同类型的异样
10.2 应用 Exception解决所有谬误
try: print(b)except Exception as result: print(result)else: print('出错了')finally: print('出错了')
10.3在适合的档次去捕捉
def A(s): return s/int(s) passdef B(s): return A(s)/2 passdef main(): try: B(0) except Exception as result: print(result)main()
在适合的地位进行谬误捕捉
division by zero
10.4 异样运行机制
1、解释器会查找相应的异样捕捉类型2、一直传递给下层,没有找到异样解决,会退出
11.自定义异样类型
class ToolongException(Exception): def __init__(self, len): self.len = len def __str__(self): return '输出的长度是'+str(self.len)+'长度,超出长度了'def name_test(): name = input('输出名字') try: if len(name)>5: raise ToolongException(len(name)) else: print(name) except ToolongException as result: print(result) else: print('没有出错了')name_test()##输出的长度是13长度,超出长度了
12 动静增加属性和办法
import typesclass Student: def __init__(self, name, age): self.name = name self.age = age pass pass def __str__(self): return '{}明天{}岁了'.format(self.name, self.age) pass passzhz = Student('詹躲躲', 25)zhz.wight = 60def dymicMethod(self): print('{}体重是{}'.format(self.name,self.wight)) pass## 动静增加属性print(zhz.wight)## 类增加属性Student.pro = '计算机科学'## 实例能够拜访print(zhz.pro)## 动静增加实例办法## import typeszhz.printInfo = types.MethodType(dymicMethod,zhz)zhz.printInfo()## 詹躲躲体重是60
13 动静绑定类办法
import typesclass Student: def __init__(self, name, age): self.name = name self.age = age pass pass def __str__(self): return '{}明天{}岁了'.format(self.name, self.age) pass passzhz = Student('詹躲躲', 25)zhz.wight = 60def dymicMethod(self): print('{}体重是{}'.format(self.name,self.wight)) pass## 动静绑定类办法@classmethoddef classTest(cls): print('类办法') pass## 动静绑定静态方法@staticmethoddef staticTest(): print('静态方法') pass
13.1.动静增加属性
print(zhz.wight)
13.2.类增加属性
Student.pro = '计算机科学'## 实例能够拜访print(zhz.pro)
13.3.动静增加实例办法
## import typeszhz.printInfo = types.MethodType(dymicMethod,zhz)zhz.printInfo()
13.4.动静绑定类办法
Student.testMethod = classTestStudent.testMethod()
13.5.动静绑定类办法 实例调用
zhz.testMethod()
13.6.动静绑定静态方法
Student.statictest = staticTestStudent.statictest()
13.7.动静绑定静态方法 实例调用
zhz.statictest()
14._slots_属性
class Student(object): __slots__ = ('name', 'age', 'score') def __str__(self): return "{},{}".format(self.name, self.age)xw = Student()xw.name = '叫我詹躲躲'xw.age = 25## print(xw.__dict__)## {'name': '叫我詹躲躲', 'age': 25}xw.s11 = '1212'#### 报错print(xw)
子类未声明 __slots__,不会继承父类的__slots__,此时子类能够随便的属性赋值
子类申明了,范畴为 子类+父类的范畴
15.题目练习 一
15.1 python new的办法和作用是什么?
用来创立实例对象,只有继承了object的话,才有这个办法。
15.2 什么是单例模式,实用于什么场景?
要求一个类有且只有一个实例,并且提供了全局的拜访点。日志插入logger,网站计数器,权限验证模块,window资源管理器,零碎回收站,数据库连接池
15.3 私有化办法和私有化属性在子类中是否继承?
不能的
15.4 在python中什么是异样?
程序在执行中呈现的异样。
15.5 python中如何解决异样?
别离依据异样的类型去解决
15.6 python中异样解决的个别格局,能够应用伪代码形容?
## try:## 失常操作## except:## ##....## else:## ##....## finally:## ##...
15.7 __slots__的作用
限度属性的随便输出,节俭内存空间
15.8 私有化的属性的作用?
爱护数据,封装性的体现
15.9 在类外是否批改公有属性?
不能够间接批改,通过办法去实现,能够借助property
15.10 如果一个类,只有指定的属性或者办法能被内部批改,该如何限度?
对属性进行私有化
16 题目练习二
16.1 定义一个person类,类中要有初始化办法,办法中要有人名,年龄两个公有属性
提供获取用户信息的函数,提供设置公有属性的办法,设置年龄在0-120岁两头,如果不在这个范畴,不能设置胜利
class Person: def __init__(self,name,age): self.__name = name self.__age = age pass pass def GetUserInfo(self): return "{}的年龄为{}".format(self.__name,self.__age) pass pass def __str__(self): return "{}的年龄为{}".format(self.__name,self.__age) def setAge(self,age): if age>0 and age<120: self.__age = age else: pass person = Person('詹躲躲',19) print(person.GetUserInfo())## 詹躲躲的年龄为19print(person.setAge(30))print(person.GetUserInfo())## 詹躲躲的年龄为30
16.2 请写一个单例模式
class DataBaseClass(object): def __new__(cls,*args,**kwargs): ## cls._instance = cls.__new__(cls) ##不能应用本人的new办法 if not hasattr(cls,'_instance'): cls._instance = super().__new__(cls,*args,**kwargs) return cls._instance pass passdb1 = DataBaseClass()db2 = DataBaseClass()db3 = DataBaseClass()print(id(db1))print(id(db2))print(id(db3))
16.3 创立一个类,并定义两个私有化属性,提供一个获取属性的办法。利用property属性给调用者提供调用
class Student: def __init__(self, name, score): self.__name = name self.___score = score @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name def __str__(self): return self def __call__(self, *args, **kwargs): print(self.name) pass passxm = Student('詹躲躲',98)xm.__call__()xm.name()
16.4 创立一个Animal类。实例一个cat对象,给cat 绑定一个run办法,给类绑定一个类属性color
import typesclass Animal: passdef run(self): print('小猫')cat = Animal()cat.run = types.MethodType(run,cat)cat.run()Animal.color = 'red'print(cat.color)def info(): print('ok')Animal.info = infoAnimal.info()
原创:叫我詹躲躲
起源:思否
链接:python面型对象编程进阶(继承、多态、私有化、异样捕捉、类属性和类办法)
致谢:感激求知教育提供的视频教程