Python - __next__() 方法中的索引如何工作?

Python - How does the index in the __next__() method work?

有人可以向我解释 __iter__()__next__() 函数如何处理索引吗?他们是基础 0 还是基础 1

我一直在玩弄它,但我想知道 Python 在后端实际上做了什么。我尝试了下面的示例 class:

>>> class my_class:
        def __init__(self, *stuff):
            self.__stuff = stuff

        def __iter__(self):
            self.__n = 0
            return iter(self.__stuff)

        def __next__(self):
            if self.__n <= len(self.__stuff):
                self.__n += 1
                return self.__stuff(self.__n)
            else:
                raise StopIteration

>>> x = my_class(1, 2, 3, 4)
>>> for each in x:
        print(each)
1
2
3
4

除非我弄错了,__next__() 使用的第一个 self.__n 值应该是 1 应该 产生,这个:

>>> for each in x:
        print(each)
2
3
4

我错过了什么?它怎么知道从 self.__stuff[0] 开始?

__iter__() 方法 returns iter(self.__stuff) 而不是 self。因此,传递给 __init__() 的元组被迭代,而不是对象。

当您调用 for each in x: 时,它不会对您的 class 定义中的 __next__() 做任何事情,因此它从您的对象属性的 1 而不是 2 开始。

即使你想调用类似 print(next(x)) 的东西,它也会给你'TypeError: 'tuple' object is not callable',因为 self.__stuff(self.__n) 无效,如 self.__stuff 是一个元组, self.__n 是一个整数。您只能调用 tuple[int] 而不能调用 tuple(int).

在你的代码提到后尝试下面的代码,它将return你想要的输出然后引发异常。

for each in x:    
    print(next(x))

结果:

2
3
4
raise StopIteration
  • 当你使用my_class时,它首先调用__init__,然后调用__iter__,最后是__next__
  • 在你的代码中,当它调用__iter__时,它return iter(self.__stuff),然后结束,没有调用__next__。所以输出就是你所看到的。
  • 如果你想调用__next__,你可以这样改变你的代码(这里__next__使用的self.__n从1开始):

    class my_class:
        def __init__(self, *stuff):
          self.__stuff = stuff
    
        def __iter__(self):
          self.__n = 0
          print('__iter__ is called')
          return self
    
        def __next__(self):
          print('__next__ is called')
          if self.__n <= len(self.__stuff):
              self.__n += 1
              return self.__stuff(self.__n)
          else:
              raise StopIteration
    
  • 提示:您可以使用print来帮助您理解代码的作用,例如上面代码中的print函数。