生成器与迭代器
Fluent Python Chapter 14读书笔记
可迭代对象¶
An iterable is an object that has an
__iter__
method which returns an iterator, or which defines a__getitem__
method that can take sequential indexes starting from zero. So an iterable is an object that you can get an iterator from.
Python中的对象,只要它定义了可以返回一个迭代器的__iter__
方法,或者定义了可以支持下标索引的__getitem__
方法,那么它就是一个可迭代对象(Iterable)。简单说,可迭代对象就是能提供迭代器的任意对象。
It’s important to be clear about the relationship between iterables and iterators: Python obtains iterators from iterables.
The most accurate way to check whether an object x is iterable is to call iter(x)
and handle a TypeError
exception if it isn’t.
Is Sentence(hello) iterable? True.
The iter
built-in function:
- Checks whether the object implements
__iter__
, and calls that to obtain an iterator. - If
__iter__
is not implemented, but__getitem__
is implemented, Python creates an iterator that attemps to fetch items in order, starting from index 0 (zero). - If that fails, Python raises
TypeError
, usually saying "C object is not iterable", where C is the class if the target object.
迭代器¶
An iterator is an object with a
__next__
and__iter__
method. 迭代器是定义了__next__
和__iter__
方法的对象。
The standard interface for an iterator has two methods:
__next__
: Returns the next available item, raisingStopIteration
when there are no more items.__iter__
: Returnsself
; this allows iterators to be used where an iterable is expected, for example, in afor
loop.
Since iterators also implement the__iter__
method, they are iterable as well.
The
time
has
come
The best way to check if an object x
is an iterator is to call isinstance(x, abc.Iterator)
.
True
Note
可迭代对象不能把自己作为迭代器。也就是说,可迭代对象有实现__next__
方法。这遵循了迭代器设计模式:如果可迭代对象实现了__next__
,它不能满足多次迭代的需要。正确的做法是将可迭代对象和迭代器分离。
生成器¶
And Python function that has the yield
keyword in its body is a generator function(生成器函数): a function which called, return a generator(生成器) object.
The __iter__
method below is a generator function which, when called, builds a generator object that implements the iterator interface, So the SentenceIterator
class is no longer needed.
A generator expression(生成器表达式) can be understood as a lazy version of a list comprehension: It does not eagerly build a list, but returns a generator that will lazily produce the items on demand.
<generator object <genexpr> at 0x107a4bb10>
hello
world