Python类中self的使用问题:Progression迭代器报错排查
嘿,我来帮你理清这个问题的关键点:
为什么原代码报错?
你猜的没错,self._current是int类型,而next()函数只能接收迭代器对象(也就是实现了__next__方法的对象),int显然不满足这个要求,所以抛出了TypeError。
为什么改成next(self)就正常了?
因为你的Progression类已经实现了__next__方法,next()函数本质上就是调用传入对象的__next__方法——只要对象有这个方法,就能被next()处理。不过这里要提个小问题:你的__iter__方法写得不对!正确的迭代器类要求__iter__返回自身(self),而你现在返回的是self._current(一个int),这不符合Python的迭代器协议。如果之后你尝试用for循环遍历这个实例,会发现还是会报错,因为for循环会先调用__iter__获取迭代器,而你返回的int不是迭代器。
self是不是迭代器类型?
首先纠正一个小误区:iter是Python的内置函数,不是类型,所以你之前写isinstance(self, iter)会报错。正确的迭代器类型是collections.abc.Iterator。要判断你的实例是不是迭代器,应该这样写:
from collections.abc import Iterator print(isinstance(self, Iterator))
但按照你现在的代码(__iter__返回self._current),这个判断会返回False。只有当你把__iter__改成返回self时,这个判断才会返回True——因为此时你的类同时实现了__iter__(返回自身)和__next__方法,完全符合迭代器的定义。
给你修正后的完整代码
我顺便把__next__的逻辑也调整了一下(原来的代码会跳过初始的start值),让它完全符合迭代器协议:
from collections.abc import Iterator class Progression: """ Iterator producing a generic progression. Default progression: 0,1,2 """ def __init__(self, start=0): self._current = start def _advance(self): """ This should be overridden by a subclass to customize progression """ self._current += 1 def __next__(self): if self._current is None: raise StopIteration() current_val = self._current self._advance() return current_val def __iter__(self): return self # 正确返回自身,满足迭代器协议 def print_progression(self, values_to_print): if self._current is not None: print(type(self)) print(isinstance(self, Iterator)) # 现在会输出True print(" ".join(str(next(self)) for _ in range(values_to_print))) # 测试一下 p = Progression(start=1) p.print_progression(3) # 会输出:1 2 3
内容的提问来源于stack exchange,提问作者joel

