运行时重写__

2024-03-28 23:03:43 发布

您现在位置: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

我还知道可以重写类定义中的默认setattr

^{pr2}$

但是,似乎不可能在运行时重写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

在最后两种情况下,dir(test)也报告了方法setattr。然而,在第一种情况下,它是正确的,在第二种情况下则不行。请注意,我也可以显式地调用它,在这种情况下它是有效的。似乎是这样,虽然方法已经定义,但它没有被正确映射以覆盖默认的赋值方法。我错过什么了吗?在

顺便说一下,我使用的是python2.7。这个问题主要是学术性的,因为从程序设计的角度来看,做这样的事情可能不是一个好主意,但它仍然值得一个答案——尽管我搜索了一下,我还是找不到它的任何文档。在


Tags: the方法testimportselffooinitdef
2条回答

请参阅Python文档的以下部分:Special method lookups for new-style classes

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.

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

它记录在Data model,“类实例”一节中:

Attribute assignments and deletions update the instance’s dictionary, never a class’s dictionary. If the class has a __setattr__() or __delattr__() method, this is called instead of updating the instance dictionary directly.

因此,无论是旧样式还是新样式,这两个检查总是针对类型,而不是实例。在

相关问题 更多 >