上课但不下课 [英] Class with iter but not next
问题描述
对于迭代器协议,您同时创建了__iter__
和__next__
方法.但是,以下情况如何呢?
For the iterator protocol you create both an __iter__
and __next__
method. However, what about the following case:
class Item:
def __init__(self):
self.name = 'James'
def __iter__(self):
return self
现在我可以做:
>>> i=Item()
>>> iter(i)
<__main__.Item instance at 0x10bfe6e18>
但不是:
>>> next(i)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
据我所知,迭代器/可迭代的定义是:
As far as I'm aware, the definition of iterator/iterable is:
- Iterable具有方法
__iter__
- 迭代器具有方法
__next__
- Iterable has the method
__iter__
- Iterator has the method
__next__
这是否意味着我上面的项目是一个Iterable而不是Iterator?还是两者都不是,因为执行以下操作无效:
Would this then mean that my item above is an Iterable but not an Iterator? Or would it be neither because doing the following wouldn't work:
>>> for item in i:
... print (item)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
请注意,这将是定义了迭代器方法的完整类:
Note this would be the full class that has the iterator methods defined:
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
推荐答案
您最正确的定义是正确的,但不完全正确.
You're mostly right with your definitions, but not quite.
- 如果对象具有返回迭代器的
__iter__
方法,则该对象是 iterable . - 如果对象具有
__next__
方法在迭代时获取下一个值,则它是 iterator .但是,Python中的迭代器也有望实现迭代.它们都应该具有返回self
的__iter__
方法.
- An object is iterable if it has an
__iter__
method that returns an iterator. - An object is an iterator if it has a
__next__
method to get the next value while iterating. But iterators in Python are also expected to be iterable. They should all have an__iter__
method that returnsself
.
您的第一个示例具有__iter__
方法,但是因为它返回self
并且该对象不是迭代器(因为它没有__next__
方法),所以它也不是有效的可迭代对象.
Your first example has an __iter__
method, but because it returns self
and the object is not an iterator (since it has no __next__
method), it's not really a valid iterable either.
要使非迭代器可迭代,您需要返回有效的迭代器其他一些对象.一种偷偷摸摸的方法是使__iter__
成为生成器方法(通过在其实现中使用yield
).但是,如果您要返回一些值序列,则也可以只在该序列上返回一个迭代器.
To make a non-iterator iterable, you need to return some other object that is a valid iterator. One sneaky way to do it is to make __iter__
a generator method (by using yield
in its implementation). But if you have some sequence of values to return, you could also just return an iterator over that sequence.
最后一个代码块中的类确实是迭代器.但是,如果您想使其不是自己的迭代器而成为可迭代的(也许是因为您希望能够对其进行多次迭代),则可能需要这样的东西:
The class in your last code block is indeed an iterator. But if you wanted to make it an iterable that is not its own iterator (perhaps because you want to be able to iterate over it several times), you would probably want something more like this:
class Item:
def __init__(self):
self.name = 'James'
def __iter__(self):
return iter(self.name)
这篇关于上课但不下课的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!