根据定义,只有一部分生成器会在一定数量的参数(具有预定义的长度)之后返回,即使这样,这些有限生成器中也只有一部分具有可预测的结束(访问生成器可能会产生副作用可以更早地停止发电机)。
如果你想为你的生成器实现长度方法,你必须首先定义你认为的“长度”(它是元素的总数吗?剩余元素的数量?),然后将你的生成器包装在一个类中。这是一个例子:
class MyFib(object):
"""
A class iterator that iterates through values of the
Fibonacci sequence, until, optionally, a maximum length is reached.
"""
def __init__(self, length):
self._length = length
self._i = 0
def __iter__(self):
a, b = 0, 1
while not self._length or self._i < self._length:
a, b = b, a + b
self._i += 1
yield a
def __len__(self):
"This method returns the total number of elements"
if self._length:
return self._length
else:
raise NotImplementedError("Infinite sequence has no length")
# or simply return None / 0 depending
# on implementation
以下是如何使用它:
In [151]: mf = MyFib(20)
In [152]: len(mf)
Out[152]: 20
In [153]: l = [n for n in mf]
In [154]: len(l)
Out[154]: 20
In [155]: l
Out[155]:
[1,
1,
2,
...
6765]
In [156]: mf0 = MyFib(0)
In [157]: len(mf0)
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
<ipython-input-157-2e89b32ad3e4> in <module>()
----> 1 len(mf0)
/tmp/ipython_edit_TWcV1I.py in __len__(self)
22 return self._length
23 else:
---> 24 raise NotImplementedError
25 # or simply return None / 0 depending
26 # on implementation
NotImplementedError:
In [158]: g = iter(mf0)
In [159]: l0 = [g.next(), g.next(), g.next()]
In [160]: l0
Out[160]: [1, 1, 2]