pax*_*blo 1 iterator python-3.x
根据文档,需要可迭代的容器应该提供一个__iter__()返回迭代器的函数。迭代器本身需要遵循迭代器协议,这意味着它必须提供__iter__()返回自身,并__next__()提供下一个项目,或者引发一个StopIterator异常的功能。
现在我明白为什么在执行自己的迭代的容器中需要这两者,因为您必须提供迭代器和下一项:
class ObjAndIter:
def __init__(self):
pass
def __iter__(self):
return self
def __next__(self):
# return something intelligent or raise StopIterator
for i in ObjAndIter():
pass
Run Code Online (Sandbox Code Playgroud)
但是,在迭代器是不同类型的情况下,我看不到迭代迭代器本身的用例。考虑一个(人为的)类,它什么也不做,只是提供一个迭代器来从给定数字向上计数到某个限制:
class MyObj:
class MyIter:
def __init__(self, start, end):
self._num = start - 1
self._end = end
def __next__(self):
self._num += 1
if self._num > self._end:
raise StopIteration
return self._num
#def __iter__(self): # This is apparently required but
# return self # it runs fine without it.
def __init__(self, start, end):
self._start = start
self._end = end
def __iter__(self):
return self.MyIter(self._start, self._end)
x = MyObj(5, 10)
for i in x:
print(i)
Run Code Online (Sandbox Code Playgroud)
现在这似乎适用于以下情况:
x = MyObj(5, 10)
for i in x:
print(i)
Run Code Online (Sandbox Code Playgroud)
尽管事实上迭代器不遵循迭代器协议 - 它提供了__next__()但不是__iter__()。该__iter__()函数仅在容器上调用,并且__next__()仅在迭代器上调用。
现在如果没有迭代器 __iter__()函数,我发现您将无法执行以下操作:
x = MyObj(5, 10)
xiter = x.__iter__()
for i in xiter:
print(i)
Run Code Online (Sandbox Code Playgroud)
但我很难想象何时需要在迭代器(而不是容器)上创建迭代器。
所以我的问题是这样的。什么情况下我需要这样做?如果没有这个,拥有迭代器协议似乎就没有什么意义了,除非容器必须提供__iter__()并且迭代器必须提供__next__()。
顺便说一句,我已经看到了这个问题及其答案,但它们似乎没有涵盖为什么迭代器需要可迭代。我可以很清楚地看到,它使代码更容易迭代容器和迭代器,但这个问题是关于为什么后者是必要的。
迭代器需要可迭代才能支持 for 循环和 iter()。
这导致:为什么要迭代迭代器?
因为有时你会直接得到迭代器,例如打开的文件或生成器函数:
>>> def gen():
... yield 1
... yield 2
...
>>> it = gen()
>>> hasattr(it, '__next__')
True
Run Code Online (Sandbox Code Playgroud)
这导致:为什么Python的某些部分返回一个interator而不是一个iterable?
这是一种告诉事物“不可倒带”/“一次性可迭代”的方法。因为返回一个可迭代对象会说“你可以对其调用两次 iter() 来迭代它两次”,这是错误的。
| 归档时间: |
|
| 查看次数: |
859 次 |
| 最近记录: |