为什么`__iter__`在定义为实例变量时不起作用?

AXO*_*AXO 9 python iteration iterable

如果我__iter__按如下方式定义方法,它将无法工作:

class A:

    def __init__(self):
        self.__iter__ = lambda: iter('text')


for i in A().__iter__():
    print(i)

iter(A())
Run Code Online (Sandbox Code Playgroud)

结果:

t
e
x
t
Traceback (most recent call last):
  File "...\mytest.py", line 10, in <module>
    iter(A())
TypeError: 'A' object is not iterable
Run Code Online (Sandbox Code Playgroud)

如您所见,调用A().__iter__()工作,但A()不可迭代.

但是,如果我__iter__为类定义,那么它将工作:

class A:

    def __init__(self):

        self.__class__.__iter__ = staticmethod(lambda: iter('text'))
        # or:
        # self.__class__.__iter__ = lambda s: iter('text')


for i in A():
    print(i)

iter(A())

# will print:
# t
# e
# x
# t
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么python设计得像这样?即为什么__iter__实例变量不起作用?难道你不觉得它不直观吗?

Zau*_*bov 5

它是通过设计完成的.您可以在此处找到详细说明:https://docs.python.org/3/reference/datamodel.html#special-method-lookup

简短回答:必须在类对象本身上设置特殊方法,以便由解释器一致地调用.

答案很长:这背后的想法是加快众所周知的结构.在你的例子中:

class A:
    def __init__(self):
        self.__iter__ = lambda: iter('text')
Run Code Online (Sandbox Code Playgroud)

你多久会在现实生活中写出这样的代码?所以,Python做了什么 - 它跳过了实例的字典查找,即iter(A())根本就没有"看到",self.__iter__实际上self.__dict__['__iter__']就是这种情况.

它还会跳过所有__getattribute__实例和元类查找,从而获得显着的加速.