python 这个类如何在不实现“next”的情况下实现“__iter__”方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1960309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:26:44  来源:igfitidea点击:

How does this class implement the "__iter__" method without implementing "next"?

pythoniteratoryield

提问by zjm1126

I have the following code in django.template:

我在 django.template 中有以下代码:

class Template(object):
    def __init__(self, template_string, origin=None, name='<Unknown Template>'):
        try:
            template_string = smart_unicode(template_string)
        except UnicodeDecodeError:
            raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.")
        if settings.TEMPLATE_DEBUG and origin is None:
            origin = StringOrigin(template_string)
        self.nodelist = compile_string(template_string, origin)
        self.name = name

    def __iter__(self):
        for node in self.nodelist:
            for subnode in node:
                yield subnode

    def render(self, context):
        "Display stage -- can be called many times"
        return self.nodelist.render(context)

The part I am confused about is below. How does this __iter__method work? I can't find any corresponding nextmethod.

我感到困惑的部分如下。这种__iter__方法是如何工作的?我找不到任何相应的next方法。

def __iter__(self):
        for node in self.nodelist:
            for subnode in node:
                yield subnode

This is the only way that I know how to implement __iter__:

这是我知道如何实施的唯一方法__iter__

class a(object):
    def __init__(self,x=10):
        self.x = x
    def __iter__(self):
        return self
    def next(self):
        if self.x > 0:
            self.x-=1
            return self.x
        else:
            raise StopIteration
 ainst = a()
 for item in aisnt:
     print item

In your answers, please try to use code examples rather than text, because my English is not very good. Thank you.

在你的回答中,请尽量使用代码示例而不是文本,因为我的英语不是很好。谢谢你。

回答by Mark Peters

From the docs:

文档

If a container object's __iter__()method is implemented as a generator, it will automatically return an iterator object (technically, a generator object) supplying the __iter__()and __next__()methods.

如果容器对象的__iter__()方法被实现为生成器,它将自动返回一个迭代器对象(从技术上讲,一个生成器对象)提供 __iter__()__next__()方法。

Here is your provided example using a generator:

这是您提供的使用生成器的示例:

class A():
    def __init__(self, x=10):
        self.x = x
    def __iter__(self):
        for i in reversed(range(self.x)):
            yield i

a = A()
for item in a:
    print(item)

回答by catchmeifyoutry

That __iter__method returns a python generator(see the documentation), as it uses the yieldkeyword. The generator will provide the next() method automatically; quoting the documentation:

__iter__方法返回一个 python生成器(请参阅文档),因为它使用yield关键字。生成器会自动提供 next() 方法;引用文档:

What makes generators so compact is that the __iter__() and next() methods are created automatically.

生成器如此紧凑的原因是 __iter__() 和 next() 方法是自动创建的。

EDIT:

编辑:

Generators are really useful. If you are not familiar with them, I suggest you readup on them, and play around with some test code.

发电机真的很有用。如果您不熟悉它们,我建议您阅读它们,并尝试一些测试代码。

Here is some more info on iterators and generators from StackOverflow.

这里有更多关于StackOverflow迭代器和生成器的信息。