Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么实现了iter的对象不能被识别为iterable?_Python_Python 3.x_Iterable - Fatal编程技术网

Python 为什么实现了iter的对象不能被识别为iterable?

Python 为什么实现了iter的对象不能被识别为iterable?,python,python-3.x,iterable,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.__ge

假设您使用包装器对象:

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)
此对象实现了
\uu iter\uu
,因为它将对它的任何调用传递给实现它的成员
f
。例如:

>>> x = IterOrNotIter()
>>> x.__iter__().__next__()
'Whatever was in /tmp/toto.txt\n'
根据文档(),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

我不明白为什么。

基本上是因为您的类没有真正的
\uuu iter\uuu
方法:

>>> hasattr(IterOrNotIter, '__iter__')
False
因此,它不符合迭代器的条件,因为对
\uuuuu iter\uuuu
的实际检查是检查是否存在,而不是假设它已实现。因此,使用
\uuuu getattr\uuuu
\uuuu getattribute\uuuuu
的变通方法(不幸的是)不起作用

这实际上在以下文件中提到:

注 当通过语言语法或内置函数进行隐式调用后查找特殊方法时,仍然可以忽略此方法。看

后一节还解释了原因:

以这种方式绕过
\uuuu getattribute\uuuu()
机器,为解释器内的速度优化提供了很大的空间,但代价是在处理特殊方法时有一定的灵活性(必须在类对象本身上设置特殊方法,以便解释器一致地调用它)


强调我的。

好吧,这让人失望。解释器检查而不是仅仅调用的事实让人觉得不和谐。@user589082是的,有点不和谐,但根据文档(我更新了答案)对于特殊的方法,这会使Python的速度大大加快,但会牺牲灵活性。@MSeifert:ok,但文档应该明确警告,在不可iterable对象上尝试使用monkey patch
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu和
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,修补的方法将被忽略,对象将引发异常并失败。否则,这是违反代码意图的不明显的“神奇”行为。@smci Python有一个问题跟踪程序。您可以要求对相关文件进行修订/澄清。
>>> hasattr(IterOrNotIter, '__iter__')
False