上课但不下课 [英] Class with iter but not next

查看:74
本文介绍了上课但不下课的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于迭代器协议,您同时创建了__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 returns self.

您的第一个示例具有__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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆