Python和for循环

Python和for循环,python,for-loop,iterable,Python,For Loop,Iterable,据我所知,我可以使用对对象进行循环构造,并使用返回迭代器的\uu iter\uu方法。我有一个对象,我为其实现了以下\uu getattribute\uu方法: def __getattribute__(self,name): if name in ["read","readlines","readline","seek","__iter__","closed","fileno","flush","mode","tell","truncate","write","writelines",

据我所知,我可以使用
对对象进行
循环构造,并使用返回迭代器的
\uu iter\uu
方法。我有一个对象,我为其实现了以下
\uu getattribute\uu
方法:

def __getattribute__(self,name):
    if name in ["read","readlines","readline","seek","__iter__","closed","fileno","flush","mode","tell","truncate","write","writelines","xreadlines"]:
        return getattr(self.file,name)
    return object.__getattribute__(self,name)
我有一个这个类的对象,
a
,它会发生以下情况:

>>> hasattr(a,"__iter__")
True
>>> for l in a: print l
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'TmpFile' object is not iterable
>>> for l in a.file: print l
...
>>>
hasattr(一个“iter”) 真的 >>>对于a中的l:打印l ... 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:“TmpFile”对象不可编辑 >>>对于文件中的l:打印l ... >>>

因此python认为
a
有一个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我做错了什么?Python2.6.4就是这样。

有一个微妙的实现细节阻碍了您的工作:
\uuuu iter\uuu
实际上不是一个实例方法,而是一个类方法。也就是说,调用了
obj.\uuuu类\uuu。iter(obj)
,而不是
obj.\uu iter()

这是由于在后台进行了插槽优化,使得Python运行时能够更快地设置迭代器。这是必需的,因为迭代器尽可能快是非常重要的


无法为基础
类型定义
\uuuu getattribute\uuuu
,因此无法动态返回此方法。这适用于大多数的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu元方法
;您需要编写一个实际的包装器。

一些特殊方法在创建类时得到了优化,以后无法添加或被赋值覆盖。请参阅有关
\uuuu getattribute\uuuuu
的说明,其中说明:

在以下情况下,此方法仍可能被忽略: 查找特殊方法作为 通过隐式调用的结果 语言语法或内置函数

在这种情况下,您需要做的是提供转发调用的
\uuu iter\uuu
的直接实现:

def __iter__(self):
    return self.file.__iter__()

+1所以这就是为什么
iter
不调用
\uuuu getattribute\uuuu
。。。正如他们所说,你每天都会学到一些新东西:)注意,你可以看到这一点的副作用(至少在CPython中):如果你定义
\uuuuu getattribute\uuuuuuuuu
,当你使用
iter
时,你会注意到它会被调用为
\uuuu class\uuuuuuuuuuuuu
,因为运行时会查找要调用的对象的类。(这可能应被视为实施细节。)