描述符:将某种特殊类型的类的实例指派给另一个类的属性。

  此处特殊类型的要求,至少实现”__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'>
>>>