描述符:将某种特殊类型的类的实例指派给另一个类的属性。
此处特殊类型的要求,至少实现”__set__(self , instance , owner)“、”__get__(self , instance , value)“、”__delete__(self , instance )“三个方法中的一个。
>>> class MyDecriptor: def __get__(self,instance,owner): print('getting...',self,instance,owner) def __set__(self,instacne,owner): print('setting...',self,instance,owner) def __delete__(self,instace): print('deleting...',self,instance) >>> class Test: x = MyDecriptor() >>>test.x getting... <__main__.MyDecriptor object at 0x00000212DA0936D8> <__main__.Test object at 0x00000212DA0EABE0> <class '__main__.Test'> >>> test.x = 'X-man' setting... <__main__.MyDecriptor object at 0x00000223972236D8> <__main__.Test object at 0x00000223972234E0> X-man >>> del test.x deleting... <__main__.MyDecriptor object at 0x00000223972236D8> <__main__.Test object at 0x00000223972234E0> >>>
test.x访问属性时,调用__get__方法,从结果可以看出,调用时传入的三个参数依次为 __main__.MyDecriptor object at 0x00000212DA0936D8,即描述符类本身的实例;第二个,<__main__.Test object at 0x00000212DA0EABE0>,Test类的实例,
第三个, <class '__main__.Test'>,类本身。
另外 __set__、__delete__与之相类似。
2、迭代器
a、定义:提供迭代方法的容器称为迭代器,序列、字典、文件等都是迭代器,它们都支持迭代操作。
for i in 'Fishc': print(i) F i s h c
此处 for语句的作用是触发迭代器的迭代功能,每次从容器中取出一个数据。
b、关于迭代操作,python提供了两个相关的 BIF、iter()、next()。对于一个容器对象,调用iter()就得到它的迭代器,调用next(),迭代器就会返回下一个值,直到迭代器没有值可以返回,就抛出StopItration异常。
>>> string = 'Fishc' >>> s =iter(string) >>> next(s) 'F' >>> next(s) 'i' >>> next(s) 's' >>> next(s) 'h' >>> next(s) 'c' >>> next(s) Traceback (most recent call last): File "<pyshell#13>", line 1, in <module> next(s) StopIteration
c、关于迭代器的魔法方法,iter()的实现 ” __iter__()“、next()的实现” __next__()“,下面斐波拉契数列的例子。
>>> class Fibs: def __init__(self,n = 10): self.a = 0 self.b = 1 self.n = n def __iter__(self): return self def __next__(self): self.a , self.b = self.b ,self.a + self.b if self.a > self.n: raise StopIteration return self.a >>> fibs = Fibs() >>> for each in fibs: print(each) 1 1 2 3 5 8 >>> fibs = Fibs(100) >>> for each in fibs: print(each) 1 1 2 3 5 8 13 21 34 55 89
4、生成器,生成器实际上是一个特殊的迭代器。
a、协同程序:可以运行的独立函数调用,函数可以暂停或者挂起,在需要的时候从程序离开的地方继续运行或重新开始。
b、一旦一个函数中存在 yield ,这个函数就成了一个生成器。
c、生成器的关键字:yield,每当遇到yield,会将后面的内容会返回,并暂停,采用next()继续。
>>> def Fibs(): a =0 b = 1 while True: a,b = b,a+b yield a >>> c = Fibs() >>> next(c) 1 >>> next(c) 1 >>> next(c) 2 >>> next(c) 3 >>> next(c) 5 >>> for each in c: if each > 100: break print(each,end=" ") 8 13 21 34 55 89 >>> type(c) <class 'generator'> >>>