3.4.1 以迭代器为例来理解多态

之前我们讲述过遍历列表、元组和字典等数据结构的方法,如果要遍历自定义类里的元素,我们需要重写关于迭代器的__iter__和__next__魔术方法。

从迭代器里,我们能体会到多态特性,针对每种不同的自定义类,迭代其中元素的动作很有可能不同,但从抽象的角度来看,迭代本身是相同的,即依次遍历自定义类里的元素。

通过多态特性,我们能以较好的代码结构来实现这类抽象的动作相同而实现细节不同的功能。在如下的IteratorDemo.py案例中,我们将通过迭代器来观察一下多态的表现形式。


01 # coding=utf-8
02 class VisitNumber:
03     def __init__(self, max):
04         self.value = 0
05         self.max = max
06     def __iter__(self):
07         return self
08     def __next__(self):
09         if(self.value == self.max):
10             raise StopIteration();
11         self.value += 1
12         return self.value
13 class VisitString:
14     def __init__(self, str):
15         self.str = str
16         self.num = len(str)
17         self.startNum = -1
18     def __iter__(self):
19         return self
20     def __next__(self):
21         self.startNum += 1
22         if self.startNum >= self.num:
23             raise StopIteration()
24         return self.str[self.startNum]
25 myNumList = VisitNumber(3)
26 for i in myNumList:
27     print(i)
28 myStrList = VisitString("Hello")
29 for char in myStrList:
30     print(char)

在第2行定义的VisitNumber类里,在第6行定义了它的__iter__方法,返回self,即实例本身,在第8行的__next__方法里定义了访问实例中下一个元素的方法。综合这两个方法,我们看到遍历VisitNumber实例的动作是依次输出指定序列里的元素。

在第13行定义的VisitString类里,在__iter__和__next__两个方法里,定义的遍历动作是依次输出字符串里的每个元素。

在两个类里,__iter__和__next__的两个方法名相同,但其中实现的遍历动作不同,由此很好地契合了抽象的动作相同(都是遍历)而实现细节不同的多态特性。