上QQ阅读APP看书,第一时间看更新
3.5 通过迭代器加深理解多态性
在3.1.2小节中,我们看到了不同的类都具有相同的魔术方法,比如当我们通过print打印某个类时,会自动触发该类的__repr__方法,也就是说,针对不同的类,__repr__方法会表现出不同的形态,体现出“多态性”。
同样,针对每个有“被遍历”需求的类,也可以让__iter__和__next__方法以多态性的方式实现各种遍历功能。比如在下面程序代码的第2行中,就是用in来遍历myList的每个元素,原因是列表对象中有能满足遍历要求的__iter__和__next__方法。
1 myList=[1,2,3,4] 2 for i in myList: # 输出1到4 3 print(i)
如果想让自定义的类具有“可遍历”的特性,即能以in的方式来输出每个元素,那么也需要覆盖(或称为重写)这两个方法。在下面的IterDemo.py范例程序中演示了“可遍历”的实现方式(也可以说是通过迭代的实现方式),通过这个范例程序让大家加深对多态性的认识。
1 # !/usr/bin/env python 2 # coding=utf-8 3 class createEven: # 有“可遍历需求”的类 4 def __init__(self, min, max): 5 self.value=min 6 self.min=min 7 self.max=max 8 def __iter__(self): # 输出全部 9 print("in iter") 10 return self 11 def __next__(self): # 生成下一个偶数 12 print("in next") 13 self.value += 2 14 return self.value 15 myEvenList=createEven(0,6) 16 for i in myEvenList: # 输出myEventList列表中不大于10的偶数 17 print(i) 18 if(i>=10): 19 break
在第8行的__iter__方法中返回了self,在第11行的__next__方法中生成了下一个偶数。在15行的程序语句创建一个包含偶数序列的myEvenList对象后,之后就能在第16行通过in来遍历其中的元素,这段代码的输出如下。
in iter in next 2 in next 4 in next 6
从执行结果可知,一旦通过in来遍历,即会触发__iter__方法,而在for循环里遍历myEvenList中的每个元素时,都会触发__next__方法。
通过这个范例程序,我们看到了“多态性”的具体实现细节,以遍历性为例时,可以在相应类中实现对应的方法(比如上面范例程序中的__iter__和__next__),于是在遍历不同类时,就会自动触发该类中的对应方法,从而让这两个方法可以针对不同的类表现出不同的形态(即多态性)。