在运行时覆盖__setattr__

Spo*_*ock 5 python

我知道在Python中可以在运行时向类添加一个方法:

class Test:
    def __init__(self):
        self.a=5

test=Test()

import types
def foo(self):
    print self.a
test.foo = types.MethodType(foo, test)
test.foo() #prints 5
Run Code Online (Sandbox Code Playgroud)

而且我也知道可以覆盖类定义中的默认setattr:

class Test:
    def __init__(self):
        self.a=5
    def __setattr__(self,name,value):
        print "Possibility disabled for the sake of this test"

test=Test() #prints the message from the custom method called inside __init__
Run Code Online (Sandbox Code Playgroud)

但是,似乎无法在运行时覆盖setattr:

class Test:
    def __init__(self):
        self.a=5

test=Test()

import types
def __setattr__(self,name,value):
    print "Possibility disabled for the sake of this test"
test.__setattr__ = types.MethodType(__setattr__, test)
test.a=10 #does the assignment instead of calling the custom method
Run Code Online (Sandbox Code Playgroud)

在最后两种情况下,dir(test)也报告方法setattr.然而,虽然在第一种情况下它可以正常工作,但在第二种情况下却没有.请注意,我也可以明确地调用它,在这种情况下它可以工作.看起来像这样,虽然已经定义了方法,但是它没有被正确映射以覆盖默认的分配方法.我错过了什么吗?

我顺便使用Python 2.7.问题主要是学术性的,因为从程序设计的角度来看这样做可能不是一个好主意,但它仍然值得一个答案 - 尽管我搜索过,但我无法在任何地方找到它.

Bri*_*n L 2

请参阅 Python 文档的这一部分:新型类的特殊方法查找

\n\n
\n

对于新式类,只有在 object\xe2\x80\x99s 类型上定义时,才能保证特殊方法的隐式调用正确工作,而不是在 object\xe2\x80\x99s 实例字典中定义。

\n
\n\n

请点击链接详细说明其背后的基本原理。据我了解,基本思想是适用于实例对象和类型对象的特殊方法(例如__repr__需要一致地调用适用于实例对象和类型对象(例如)的特殊方法,而不是有时需要显式参数,有时接收隐式参数。通过始终调用对象类型的方法,我们知道始终传递显式参数 - 但副作用是绕过实例字典。

\n