我从python 2.7.8的官方文档中学到了如何使用迭代器和生成器。我有一个关于好奇心的问题。
it = iter("abcde")
print it
>>> <iterator object at 0x7ff4c2b3bad0>
class example1():
def __init__(self, word):
self.word = word
self.index = len(word)
def __iter__(self):
for x in range(self.index - 1, -1, -1):
yield self.word[x]
a = example1("altalena")
print iter(a)
>>> <generator object __iter__ at 0x7f24712000a0>
在上面的例子中,当我打印迭代器时,我读取“generator”,“iterator”对象和十六进制ID。为什么我不能用以下代码做同样的事情?
class example2():
def __init__(self, word):
self.word = word
self.index = len(word)
def __iter__(self):
return self
def next (self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.word[self.index]
a = example2()
print iter(a)
>>> <__main__.example2 instance at 0x7f89ee2de440>
我认为它是由 iter 中的“return self”引起的,这导致了类实例,但我不知道获得更正确输出的解决方案。它可能没用,但我不知道为什么它是如何避免它。
答案 0 :(得分:0)
我认为你没有问题,你只是不明白这里发生了什么。
通常,iter(object)
返回此可迭代对象的迭代器。
这可以通过调用__iter__()
获得,或者,如果不存在,则通过提供一个调用__getitem__()
的包装器对象直到它耗尽(引发IndexError
)来获得。
__iter__()
返回的对象可以是迭代本身(如第二个示例中所示)或其他内容。特别是,如果你像第一个例子那样使__iter__()
成为一个生成器函数,它就可以是一个生成器对象。
迭代本身发生在迭代器对象及其next()
resp上。 __next__()
方法。
答案 1 :(得分:0)
生成器是一种迭代器。您的example1
类正在返回生成器,因为您在yield
中使用了__iter__
;它是从__iter__
返回的单独的迭代器对象。这使得example1
类可迭代,而不是迭代器本身。
在您的第二个示例中,您的班级__iter__
会返回self
。它不仅是可迭代的,而是它自己的迭代器。因为它返回self
,这里没有单独的对象。
Python明确区分了 iterable 和 iterator 。 可迭代可以潜在进行迭代。迭代时,迭代器执行实际工作。通过使用iter()
,您可以让Python为给定的可迭代生成迭代器。
这就是iter(stringobject)
返回新对象的原因;您已从 iterable 字符串中生成迭代器。
你需要这种区别,因为迭代过程需要保持状态的东西;即我们现在在哪里。 迭代器是跟踪它的对象,因此每次在迭代器上调用.next()
方法时,都会获得下一个值,或者如果StopIteration
被提升,则会引发example1
没有下一个值可以再生产。
因此,在您的示例中,字符串和iter()
都只是 iterable ,并且在它们上调用example2
会生成一个新的单独的迭代器。
但是,您的iter()
是拥有 迭代器。在其上调用example2
不会产生单独的对象。您无法从已 迭代器的内容创建单独的迭代器。
如果要为__iter__
类生成新的独立迭代器,则需要从class ExampleIterator(object):
def __init__(self, source):
self.source = source
self.position = len(source)
def __iter__(self):
return self
def next(self):
if self.position <= 0:
raise StopIteration
self.position -= 1
return self.source[self.position]
class Example2():
def __init__(self, word):
self.word = word
def __iter__(self):
return ExampleIterator(self)
返回一个独立的独立对象:
Example2
此处__iter__
只是可迭代的,而不是迭代器。 ExampleIterator()
方法返回一个新的,不同的{{1}}实例,它负责跟踪迭代状态。