这个类如何实现"__iter__"方法而不实现"next"?
我在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
在你的回答中,尽量使用代码示例而不是文字,因为我的英语不是很好。
2 个回答
16
这个 __iter__
方法会返回一个 Python 的生成器(你可以查看 文档了解更多),因为它使用了 yield
这个关键词。生成器会自动提供 next()
方法;引用文档中的话:
生成器之所以这么简洁,是因为
__iter__()
和next()
方法是自动创建的。
编辑:
生成器真的很有用。如果你对它们不太了解,我建议你去了解一下,并尝试写一些测试代码。
这里还有一些关于迭代器和生成器的更多信息,来自 StackOverflow。
41
来自文档:
如果一个容器对象的
__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)