gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 17:16:14 25 4
gpt4 key购买 nike

假设您使用包装器对象:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com