chapter10.2基础知识点补充
__slots__
最简单的hash算法,取余,便于理解模型
字典为了提高查询效率,使用空间换时间
实例的属性都需要一个空间,里边只放一两个了浪费
解决数百万个对象问题,字典就太多了
此时就可以用slots解决,只要定义了__slots__,对象的字典消失
__slots__中没有的属性,对象不能添加
__slots__中的属性,可以在定义对象时先没有全部属性
尝试为实例增加动态属性时,会失败,为类增添类的属性不受影响。
class A: X = 100 __slots__ = ('x', 'y') ##元祖可以 #__slots__ = ['y','x'] ##列表可以 #__slots__ = 'y', 'x' ##自动封成元祖 #__slots__ = 'y' def __init__(self): self.x = 5 self.y = 4 def show(self): print(self.X, self.y) a = A() a.show() print("A",A.__dict__) #print('a',a.__dict__)
不影响子类的实例,不会继承,只对自己的实例的字典生效。节约内存可以用元组,列表问题也不大
需要构建数百万的以上的对象,且内存容量较为紧张时使用。实例的属性简单,固定且不用动态增加的场景
在生产中一般不用,知识点,内存受限的开发时,才会考虑用slots
一般都是多用内存来提高效率,要求时间时,用空间来换
未实现和未实现的异常
NotImplemented 是个值,是个单值
不是None,文档是==None,但它不是None
内建对象,未定义的值,自己有类,
类型和继承是两条线
运算符重载中的反向方法
__add__,__iadd__ 运算符重载
radd 反向加法,
class A: def __init__(self): self.x = 4 def __add__(self, other): print('A add') if hasattr(other,'x'): return self.x+other.x try: x = int(other) except: x = 0 return self.x + x def __radd__(self, other): print("A radd") return self.__add__(other) class B: def __init__(self): self.x = 2 def __add__(self, other): print('B add') if isinstance(other,type(self)): return self.x + other.x else: return NotImplemented a = A() b = B()
A类的实例实现了加法,B类的实例没有实现加法,a+b时调用a的__add__方法,b+a时报错
A类的实例实现了反向加法,b+a时,如果B类没有加法,就会调用A类的反向加法,B类加法返回NotImplemented,未实现时解释器会自动调第二对象的__radd__方法
1+a时,1在调用自身的加法后,会判断第二个值得类型,不是int,就会尝试调第二个值的__radd__方法,字符串也是一样的方法。
生成器交互
生成器提供了send方法,可以和生成器沟通
调用send,就可以把send的实参传给yield语句做结果,这个结果可以在等式右边被赋值给其他变量
send和next一样可以推动生成器启动执行
def inc(): count = 0 while True: response = yield count if response: count = response count += 1 g = inc() print(next(g)) print(g.send(5))