为什么__getattr__能够处理python 2.x中的内置运算符重载?

fpg*_*ost 4 python class

在python 2.x中取以下类:

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
Run Code Online (Sandbox Code Playgroud)

现在,如果您创建一个实例并在shell中调用它(要调用__repr__),就像

 p = Person('Bob')
 p
Run Code Online (Sandbox Code Playgroud)

你得到

Fetching attr: __repr__
Bob
Run Code Online (Sandbox Code Playgroud)

如果没有__getattr__超载,你就会得到默认<__main__.A instance at 0x7fb8800c6e18>的东西.

我的问题是,为什么内置__getattr__甚至能够处理__repr__(以及其他类似的内置)调用,如果它们没有在其他地方定义.这些属性不是运算符,更像是方法..

(这不再适用于python 3.x所以我猜他们已经摆脱了内置函数__getattr__的处理.)

Ash*_*ary 7

它不是Python 2或3的东西,它是一种新式和旧式的东西.在旧式类中,这些方法没有特殊含义,它们被视为简单属性.

在新式类中,特殊方法总是在类中查找(隐式查找)而不是实例.

对于新式类,只有在对象的类型上定义,而不是在对象的实例字典中,才能保证对特殊方法的隐式调用才能正常工作.

旧式课程:

对于旧式类,始终以与任何其他方法或属性完全相同的方式查找特殊方法.无论是以何种方式明确地查找方法,x.__getitem__(i)还是隐式地查找方法,都是 如此x[i].

相关:覆盖实例上的特殊方法