Why is __getattr__ capable of handling built-in operator overloads in python 2.x?

六眼飞鱼酱① 提交于 2020-01-14 10:48:51

问题


In python 2.x take the following class:

class Person:
    def __init__(self, name):
        self.name = name

    def myrepr(self):
        return str(self.name)

    def __getattr__(self, attr):
        print('Fetching attr: %s' % attr)
        if attr=='__repr__':
            return self.myrepr

Now if you create an instance and echo it in the shell (to call __repr__), like

 p = Person('Bob')
 p

You get

Fetching attr: __repr__
Bob

Without the __getattr__ overload you'd have just got the default <__main__.A instance at 0x7fb8800c6e18> kind of thing.

My question is why is the built-in __getattr__ even capable of handling calls to __repr__ (and other builtins like that) if they are not elsewhere defined. These are not attributes they are operators, more like methods..

(This no longer works in python 3.x so I guess they got rid of the handling by __getattr__ of the builtins.)


回答1:


It's not a Python 2 or 3 thing, it's a new-style vs old-style class thing. In old-style classes these methods had no special meaning, they were treated like simple attributes.

In new-style classes the special methods are always looked up in the class(implicit lookup) not instance.

For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

Old-style classes:

For old-style classes, special methods are always looked up in exactly the same way as any other method or attribute. This is the case regardless of whether the method is being looked up explicitly as in x.__getitem__(i) or implicitly as in x[i].

Related: Overriding special methods on an instance



来源:https://stackoverflow.com/questions/27081448/why-is-getattr-capable-of-handling-built-in-operator-overloads-in-python-2-x

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!