在__iter__方法中返回self的用途是什么?

问题描述 投票:6回答:3
def __iter__(self):
    return self 

只是想知道上面的代码通常做了什么,为什么需要它。

我经历了许多代码教程和块,没有任何正确的规范得到多个答案,只是一个简短的解释将是伟大的。

python python-2.7
3个回答
3
投票

编辑:2.7而不是3

这是我的理解

在下面的示例代码中,我们可以说类Testing是一个可迭代的对象,因为我们使用__iter__实现它。方法__iter__返回一个迭代器。迭代器使用下一个方法来确定迭代的下一个值。如果我要从下面的类中删除next方法,代码将失败。

iterable =一个可以迭代的对象...用__iter__实现

iterator =定义如何迭代的对象......从字面上看,下一个值是什么。这是用__next__实现的

因此,您质疑的代码实际上采用了类对象(self是参数)并返回一个迭代器,这使得类对象可迭代。因此,在下面的示例中,我们实际上可以迭代类对象myObj。

class Testing:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def __iter__ (self):
        return self
    def next(self):
        if self.a <= self.b:
            self.a += 1
            return self.a-1
        else:
            raise StopIteration

myObj = Testing(1,5)           
for i in myObj:
    print i

2
投票

这也困惑了我一段时间:)好吧,让我们在python中看到一个for循环:

for i in a:
    print i

在这个片段中,for循环将隐式调用a.iter(),它应该是一个迭代器。更多,在python中,如果你想要一个迭代器,该类必须实现'iterator'接口,这意味着它应该同时具有_iter__和_next__,__iter__的效果是返回迭代器。

但是,python中有另一个概念,它可以调用iterable,它是一个可以生成迭代器的工厂。

好了,现在,我们想要的是迭代器或迭代器,因此,它们的iter方法必须返回一个迭代器。

对于iterable,它应该返回一个迭代器(可能是另一个类实现'iterator'接口),对于迭代器,是的,它本身就是一个迭代器,所以只返回它自己!

以下代码段是来自Fluent Python的副本:

import reprlib

RE_WORD = re.compile('\w+')


class Sentence:
    def __init__(self, text):
        self.text = text
        self.words = RE_WORD.findall(text)

    def __repr__(self):
        return 'Sentence(%s)' % reprlib.repr(self.text)

    def __iter__(self):
        return SentenceIterator(self.words)


class SentenceIterator:
    def __init__(self, words):
        self.words = words
        self.index = 0

    def __next__(self):
        try:
            word = self.words[self.index]
        except IndexError:
            raise StopIteration()
        self.index += 1
        return word

    def __iter__(self):
        return self
s = Sentence('"The time has come," the Walrus said,')

你可以做:

   for i in iter(s):
       print(s)

和:

   for i in s:
       print(s)

如果删除__iter__in迭代器,则只能使用:

 for i in s:
     print(s)

因为iter(s)在迭代器类中删除__iter__时不再是迭代器


1
投票

这有点令人困惑。简而言之,定义__iter__以返回self实际上是将迭代器对象快速转换为可迭代的,以便您可以在for循环中使用它。

回想一下,迭代器是一个具有下一个方法的对象,用于在执行迭代的过程中返回下一个项目。调用下一个方法后,迭代器的状态会发生变化。

回想一下,iterable是一个带有__iter__方法的对象,其目的是返回一个新的迭代器来执行迭代。

为了分离概念,让我们以迭代器OneToFourIterator和可迭代的OneToFourIterable为例。

class OneToFourIterator:
  def __init__(self):
    self.state = 0
  def next(self):
    self.state += 1
    if self.state > 4:
      raise StopIteration
    return self.state

class OneToFourIterable:
  def __init__(self):
    pass
  def __iter__(self):
    return OneToFourIterator()

要使用for循环执行迭代,你必须给它一个像这样的迭代,

for i in OneToFourIterable():
  print i

如果在for循环中使用迭代器,则会出错。要使用迭代器进行迭代,您可以执行类似的操作

iterator = OneToFourIterator()
while True:
  try:
    current = iterator.next()
    print current
  except StopIteration:
    break

最后,我认为人们定义__iter__以返回self的原因是,不是像上面那样编写2个类,而是可以快速将迭代器转换为迭代,以便可以在for循环中使用它:

class OneToFourIteratorAndIterable:
  def __init__(self):
    self.state = 0
  def next(self):
    self.state += 1
    if self.state > 4:
      raise StopIteration
    return self.state
    pass
  def __iter__(self):
    return self

for i in OneToFourIteratorAndIterable():
  print i
© www.soinside.com 2019 - 2024. All rights reserved.