为什么将__iter__定义为实例变量时不起作用? [英] Why `__iter__` does not work when defined as an instance variable?

查看:80
本文介绍了为什么将__iter__定义为实例变量时不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我按以下方式定义 __ iter __ 方法,它将无法正常工作:

If I define the __iter__ method as follows, it won't work:

class A:

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


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

iter(A())

结果:

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

如您所见,调用 A().__ iter __()是可行的,但是 A()是不可迭代的.

As you can see, calling A().__iter__() works, but A() is not iterable.

但是,如果我为该类定义 __ iter __ ,那么它将起作用:

However if I define __iter__ for the class, then it will work:

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

有人知道为什么为什么要这样设计python吗?即为什么 __ iter __ 作为实例变量不起作用?你不觉得它不直观吗?

Does anyone know why python has been designed like this? i.e. why __iter__ as instance variable does not work? Don't you find it unintuitive?

推荐答案

这是设计使然.您可以在此处找到完整的描述: https://docs.python.org/3/reference/datamodel.html#special-method-lookup

It is done by design. You can find the thorough description here: https://docs.python.org/3/reference/datamodel.html#special-method-lookup

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

Short answer: the special method must be set on the class object itself in order to be consistently invoked by the interpreter.

长答案:这背后的想法是加快知名的建筑.在您的示例中:

Long answer: the idea behind this is to speed up well-known constructions. In your example:

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

在现实生活中,您将多久编写一次这样的代码?因此,Python的作用-跳过实例的字典查找,即 iter(A())根本不会看到"该 self .__ iter __ ,实际上在这种情况下 self .__ dict __ ['__ iter __'] .

How often are you going to write a code like this in real life? So, what Python does - it skips a dictionary lookup of the instance, i.e. iter(A()) simply does not "see" that self.__iter__, which is actually self.__dict__['__iter__'] in this case.

它还将跳过所有 __ getattribute __ 实例和元类查找,从而显着提高了速度.

It also skips all the __getattribute__ instance and metaclass lookup gaining a significant speedup.

这篇关于为什么将__iter__定义为实例变量时不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆