此类如何实现“ __iter__”方法而不实现“ next”?

问题描述 投票:21回答:2

我在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)

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

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

这是我知道如何实现__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

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

python iterator yield
2个回答
39
投票

docs

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

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

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)

15
投票

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

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

编辑:

生成器非常有用。如果您不熟悉它们,建议您阅读它们,并试用一些测试代码。

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

© www.soinside.com 2019 - 2024. All rights reserved.