Dav*_*542 5 python iterator language-lawyer
对于迭代器协议,您创建一个__iter__and__next__方法。然而,下面的情况又如何呢:
class Item:
def __init__(self):
self.name = 'James'
def __iter__(self):
return self
Run Code Online (Sandbox Code Playgroud)
现在我可以做:
>>> i=Item()
>>> iter(i)
<__main__.Item instance at 0x10bfe6e18>
Run Code Online (Sandbox Code Playgroud)
但不是:
>>> next(i)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
Run Code Online (Sandbox Code Playgroud)
据我所知,迭代器/可迭代的定义是:
__iter____next__那么这是否意味着我上面的项目是一个 Iterable 但不是一个 Iterator?或者两者都不是,因为执行以下操作是行不通的:
>>> for item in i:
... print (item)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
Run Code Online (Sandbox Code Playgroud)
请注意,这将是定义了迭代器方法的完整类:
class Item:
def __init__(self):
self.name = 'James'
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i >= len(self.name): raise StopIteration
value = self.name[self.i]
self.i += 1
return value
Run Code Online (Sandbox Code Playgroud)
您的定义大部分是正确的,但不完全正确。
__iter____next__但 Python 中的迭代器也应该是可迭代的。它们都应该有一个__iter__返回 的方法self。您的第一个示例有一个__iter__方法,但因为它返回self并且该对象不是迭代器(因为它没有__next__方法),所以它也不是真正有效的可迭代对象。
要使非迭代器可迭代,您需要返回一些其他有效迭代器的对象。一种偷偷摸摸的方法是创建__iter__一个生成器方法(通过yield在其实现中使用)。但是,如果您要返回一些值序列,您也可以只返回该序列上的迭代器。
最后一个代码块中的类确实是一个迭代器。但是,如果您想让它成为一个不是其自己的迭代器的可迭代对象(也许是因为您希望能够对其进行多次迭代),您可能会想要更像这样的东西:
class Item:
def __init__(self):
self.name = 'James'
def __iter__(self):
return iter(self.name)
Run Code Online (Sandbox Code Playgroud)