目录
1. manually consuming an iterator
3. creating new iteration patterns with generators
1. manually consuming an iterator
解决问题: 不使用loop来处理iterable里items
方法: 使用next()方法 + catch the StopIteration exception
with open('sourcefile.txt') as f:
# 使用loop:
for line in f.readlines():
print(line, end='')
# 不使用loop
try:
while True:
line = next(f)
print(line, end='')
except StopIteration:
pass
通常使用StopIteration来捕捉iteration的结束
但是, 如果是像上面那样手动调用next(), 则可以让next()返回一个terminating value, 如None
with open('sourcefile.txt') as f:
while True:
line = next(f, None)
if line is None:
break
print(line, end='')
2. delegationg iteration
解决问题: you have built a custom container object that internally holds a list, tuple, or some other iterable. You would like to make iteration work with your new container
方法:定义一个 __iter__() method that delegates iteration to the internally held container
class Node:
def __init__(self, value):
self._value = value
self._children = []
def __repr__(self):
return 'Node({!r})'.format(self._value)
def add_child(self, node):
self._children.append(node)
#forwards the iteration request to the internally held _children attribute
def __iter__(self):
return iter(self._children)
if __name__ == '__main__':
root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_child(child1)
root.add_child(child2)
for ch in root:
print(ch)
3. creating new iteration patterns with generators
解决问题: You want to implement a custom iteration pattern that’s different than the usual builtin functions (e.g., range(), reversed(), etc.).
方法:使用generator function
def frange(start, stop, increment):
x = start
while x < stop:
yield x
x += increment
for n in frange(0, 4, 0.5):
print(n)
print(list(frange(0, 1, 0.125)))
yield: turn a function into a generator
和普通函数不同的是, generator function only runs in response to “next” operations carried out in iteration. However, the for statement that’s usually used to iterate takes care of these details, so you don’t normally need to worry about them.