python - 为什么实现了 __iter__ 的对象不被识别为可迭代的?

标签 python python-3.x iterable

假设您使用包装器对象:

class IterOrNotIter:
    def __init__(self):
        self.f = open('/tmp/toto.txt')
    def __getattr__(self, item):
        try:
            return self.__getattribute__(item)
        except AttributeError:
            return self.f.__getattribute__(item)

这个对象实现了__iter__,因为它将对它的任何调用都传递给实现它的成员f。恰当的例子:

>>> x = IterOrNotIter()
>>> x.__iter__().__next__()
'Whatever was in /tmp/toto.txt\n'

根据文档 ( https://docs.python.org/3/library/stdtypes.html#iterator-types ),IterOrNotIter 因此应该是可迭代的。

但是,Python 解释器无法将 IterOrNotIter 对象识别为实际可迭代对象:

>>> x = IterOrNotIter()
>>> for l in x:
...    print(l)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'IterOrNotIter' object is not iterable

虽然这是可行的:

>>> x = IterOrNotIter()
>>> for l in x.f:
...    print(l)
...
Whatever was in /tmp/toto.txt

我不明白为什么。

最佳答案

基本上是因为你的类没有真正的 __iter__ 方法:

>>> hasattr(IterOrNotIter, '__iter__')
False

所以它不符合迭代器的条件,因为对 __iter__ 的实际检查是检查是否存在,而不是假设它已实现。因此,使用 __getattr____getattribute__ 的解决方法(不幸的是)不起作用。

__getattribute__ 的文档中实际上提到了这一点:

Note

This method may still be bypassed when looking up special methods as the result of implicit invocation via language syntax or built-in functions. See Special method lookup.

后一部分还解释了原因:

Bypassing the __getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).

强调我的。

关于python - 为什么实现了 __iter__ 的对象不被识别为可迭代的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43935187/

相关文章:

python - 向 CSV 文件添加一行 - TypeError : must be str, 不是元组

python - [Learning Python]一书中说range是一个generator——这是假的吗?

python - Unittest 的 assertEqual 和 iterables - 只检查内容

Python - 如果字符串元素本身包含空格,如何用空格分割?

python - Numpy:替换数组中的随机元素

python - 包含重复索引的两个以上 DataFrame 的笛卡尔积

python - pandas dataframe sum 与 groupby

python - 无法创建能够满足特定条件的 xpath

python - 如何处理 InvalidSchema 异常

python - Django: "Object is not iterable",当尝试修改所述对象时