多态
1.多态
多态指的是一类事物有多种形态
在程序中多个不同类对象可以响应同一个方法,产生不同的结果
好处: 对于使用者,降低了使用难度,
实现多态: 接口,抽象类,鸭子类型都可以写出具备多态的代码
class Ji: def brak(self): print('咯咯咯') def spawn(self): print('下鸡蛋') class Ya: def brak(self): print('咯咯咯') def spawn(self): print('下鸭蛋') class E: def brak(self): print('咯咯咯') def spawn(self): print('下鹅蛋') j = Ji() y = Ya() e =E() def manage(obj): obj.spawn() manage(j) # 下鸡蛋 manage(y) # 下鸭蛋 manage(e) # 下鹅蛋
isinstance, 判断一个对象是否是某个类的实例, 参数1 判断的对象, 参数2 判断的类型
def add_num(a,b): if isinstance(a,int) and isinstance(b,int): return a + b return None print(add_num(20,40)) # 60
issubclass, 判断一个类是否是另一个类的子类, 参数一是子类, 参数二是父类
class Animal: def eat(self): print('动物吃东西') class Pig(Animal): def eat(self): print('猪吃东西') class Tree: def light(self): print('光合作用') pig = Pig() t = Tree() def manage(obj): if issubclass(type(obj),Animal): obj.eat() else: print('不是一头动物') manage(pig) # 猪吃东西 manage(Tree) # 不是一头动物 print(issubclass(Tree,object)) # True
str
__str__ 会在对象被转换为字符串时,转换的结果就是这个函数的返回值
使用场景:利用该函数来定义,对象就是打印格式
del
执行时机: 手动删除对象立马执行,或是程序结束时也会自动执行
使用场景:对象在使用过程中,打开了不属于解释器的资源,例如文件
mport sys import time class Person: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '这是一个person对象 name:%s age:%s'%(self.name,self.age) def __del__(self): print('del run') p = Person('jack','20') print(p) # 这是一个person对象 name:jack age:20 del p #del run print('over') # over
class FileTool: def __init__(self,path): self.file = open(path,'rt',encoding='utf-8') self.a = 100 def read(self): return self.file.read() def __del__(self): self.file.close() tool = FileTool('a.txt') print(tool.read()) # alhfkdjfhjkhaklf
call: 执行时机: 在调用对象时,自动执行
class A: def __call__(self,*args,**kwargs): print('call run') print(args) print(kwargs) a = A() a(1,a=100) # call run (1,) {'a': 100}
slots: 该属性是一个类属性,用于优化对象内存占用
优化的原理,将原本不固定的属性变量,变得固定了,解释器就不会为对象创建名称空间了,从而达到减小内存开销的效果
当类中出现了slots时将导致这个类的对象无法在添加新的属性
import sys class Person: __slots__ = ['name'] def __init__(self,name): self.name = name p = Person('jason') print(p) # <__main__.Person object at 0x00000197841B75B8> print(sys.getsizeof(p)) # 48
__getattr__: 用点访问属性时,如果属性不存在, 返回None
__setattr__: 用点设置属性
__delattr__: 用del删除属性
__getattribute__: 用点访问属性
在获取属性时如果存在getattribute, 则先执行该函数,如果没有拿到属性则继续调用 getattr函数,如果拿到了则直接返回,如果没拿到返回None
class A: def __setattr__(self, key, value): print(key) print(value) print('__setattr__') def __delattr__(self, item): print('__delattr__') def __getattr__(self, item): print('__getattr__') def __getattribute__(self, item): print('__getattribute__') a = A() a.name = 'jack' # name jack __setattr__ print(a.name) # __getattribute__ None del a.name # __delattr__ print(a.name) # __getattribute__ None print(a.xxx) __getattribute__ None
class A: def __getitem__(self,item): print('__getitem__') return self.__dict__[item] def __setitem__(self,key,value): print('__setitem__') self.__dict__[key] = value def __delitem__(self, key): del self.__dict__[key] print("__delitem__") a = A() a.name = 'jack' a["name"] = 'jack' # __setitem__ print(a["name"]) # __getitem__ jack del a["name"] # __delitem__
class MyDict(dict): def __getattr__(self,key): return self.get(key) def __setattr__(self,key,value): self[key] = value def __delattr__(self,item): del self[item] a = MyDict() a["name"] = 'jack' print(a["name"]) # jack
判断两个对象某个属性的大小
class Student(object): def __init__(self,name,height,age): self.name = name self.height = height self.age = age def __gt__(self, other): return self.height > other.height def __it__(self,other): return self.height < other.height def __eq__(self, other): if self.name == other.name and self.age == other.age and self.height == other.height: return True return False stu1 = Student('jack',180,27) stu2 = Student('rose',170,17) print(stu1 < stu2) # False print(stu1 == stu2) # False
运算符重载
当我们在使用某个符号时,python解释器都会为这个符号定义一个含义,同时调用对应的处理函数, 当我们需要自定义对象的比较规则时,就可在子类中覆盖 大于 等于 等一系列方法....
迭代器协议
迭代器是具有__iter__和__next__的对象, 给对象增加这两个方法让对象变成一个迭代器
class MyRange: def __init__(self,start,end,step): self.start = start self.end = end self.step = step def __iter__(self): return self def __next__(self): a = self.start self.start += self.step if a < self.end: return a else: raise StopIteration for i in MyRange(1,10,2): print(i) # 1 3 5 7 9
上下文管理
在python中,上下文可以理解为是一个代码区间,一个范围 ,例如with open 打开的文件仅在这个上下文中有效, enter表示进入上下文, exit表示退出上下文
当执行with 语句时,会先执行enter , 当代码执行完毕后执行exit,或者代码遇到了异常会立即执行exit,并传入错误信息, 错误信息包含错误的类型.错误的信息.错误的追踪信息
class MyOpen(object): def __init__(self,path): self.path = path def __enter__(self): self.file = open(self.path) return self def __exit__(self,exc_type,exc_val,exc_tb): self.file.close() return True with MyOpen('a.txt')as m: print(m) # <__main__.MyOpen object at 0x000001D445D07DD8> print(m.file.read()) # alhfkdjfhjkhaklf '123'+1
enter函数应该返回对象自己, exit可以有返回值,是一个bool类型,用于表示异常是否被处理,仅在上下文中出现异常有用, 如果为True 则意味着异常已经被处理了, False,异常未被处理, 程序将中断报错
enter与del的区别: del管理的是对象的生命周期, 会在对象销毁时执行清理,