一般我们在类里面写迭代器都是如下写法:
1 class IterableSomthing: 2 def __iter__(self): 3 return self 4 5 def __next__(self): 6 return 1
但是,《流畅的python》给出了不同的见解。该书指出,在数据结构内实现迭代器是个很蠢的想法,因为需要引入游标指针记录位置的缘故,这么实现迭代器会造成数据结构空间性能下降,同时,因为游标指针的独立性使得改数据结构无法并发遍历,所以又造成了时间性能的下降。代码如下
1 class Node: 2 def __init__(self, item): 3 self.item = item 4 self.pre = None 5 self.next = None 6 7 8 class Deque: 9 def __init__(self): 10 """创建一个空的双端队列""" 11 self.head = None 12 self.tail = None 13 self.point = self.head #游标指针 14 15 def add_front(self, item): 16 """从队头加入一个item元素""" 17 n0 = Node(item) 18 if self.head: 19 n0.next = self.head 20 self.head.pre = n0 21 self.head = n0 22 else: 23 self.head = n0 24 self.tail = n0 25 self.zero() 26 27 def add_rear(self, item): 28 """从队尾加入一个item元素""" 29 n0 = Node(item) 30 if self.tail: 31 n0.pre = self.tail 32 self.tail.next = n0 33 self.tail = n0 34 else: 35 self.head = n0 36 self.tail = n0 37 self.zero() 38 39 def remove_front(self): 40 """从队头删除一个item元素""" 41 if self.head: 42 if self.head == self.tail: 43 self.head = None 44 self.tail = None 45 else: 46 self.head.next.pre = None 47 self.head = self.head.next 48 self.zero() 49 50 def remove_rear(self): 51 """从队尾删除一个item元素""" 52 if self.tail: 53 if self.head == self.tail: 54 self.head = None 55 self.tail = None 56 else: 57 self.tail.pre.next = None 58 self.tail = self.tail.pre 59 self.zero() 60 61 def is_empty(self): 62 """判断双端队列是否为空""" 63 return self.head is None 64 65 def size(self): 66 """返回队列的大小""" 67 i = 0 68 n0 = self.head 69 while n0: 70 i += 1 71 n0 = n0.next 72 return i 73 74 def tolist(self): 75 li = [] 76 n0 = self.head 77 while n0: 78 li.append(n0.item) 79 n0 = n0.next 80 return li 81 82 def gen(self): 83 n0 = self.head 84 while n0: 85 # print(id(self)) 86 yield n0.item 87 n0 = n0.next 88 raise StopIteration 89 90 def __iter__(self): 91 # n0 = self.head 92 # while n0: 93 # # print(id(self)) 94 # yield n0.item 95 # n0 = n0.next 96 # raise StopIteration 97 return self 98 99 def __next__(self): 100 if self.point: 101 n0 = self.point 102 self.point = self.point.next 103 return n0.item 104 else: 105 self.zero() 106 raise StopIteration 107 108 def zero(self): #游标指针归零函数 109 self.point = self.head
这是个双端队列的python实现,如果实现了迭代器,就必须实现游标指针类属性,游标指针归零类方法,着实降低了开发效率
有没有别的解决方法呢?
有
只要改一处:
1 def __iter__(self): 2 __index_temp = self.__head 3 while __index_temp: 4 n0 = __index_temp 5 __index_temp = __index_temp.next 6 yield n0 7 else: 8 raise StopIteration
对你没看错,没有__next__函数!没有游标指针!没有归零函数!
这个__iter__函数需要返回一个迭代器,我们就给他一个,因为生成器也是迭代器!
此时,这个双端队列的python实现就不是一个迭代器了,而是一个可迭代对象,就可以用for循环迭代了
def test2(): s1 = DoubleLinkList() for i in range(1000): s1.append(i) for ii in s1: print(ii.item) if ii.item == 500: print(‘------------------------------------------------------------------------------‘) break for ii in s1: print(ii.item)
而且每一个for循环都是独立的,因为每个for循环块获得的对象都是一个独立的生成器,相互之间不会干扰,虽然看起来都是调用同一个对象,但实际上完全不是这么一回事,这就和list的实现是一样一样的,这样的话做并发循环就容易多了。
思考:python里的魔术方法都很有用,但是我们是要为了实现某个功能专门实现对应的魔术方法呢,还是直接实现对应的功能函数呢?
魔术方法是为了其他方法服务的基本方法,还是锦上添花的增补手段呢?
时间: 2024-10-01 02:42:22