python __iter__和next()打印输出的说明

时间:2014-08-04 12:04:41

标签: python class iterator generator theory

我从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”引起的,这导致了类实例,但我不知道获得更正确输出的解决方案。它可能没用,但我不知道为什么它是如何避免它。

2 个答案:

答案 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}}实例,它负责跟踪迭代状态。