如何取消覆盖__setattr__方法?

时间:2012-02-07 18:38:07

标签: python class object dynamic setattr

这个问题的目标是了解“内置”是如何在python中内置函数。

如果我覆盖setattr方法,我该如何取回它?例如,我有这样的课程“工作”:

class WorkingSetAttr:
    def a(self): return 'a'
    def b(self): return 'b'

和类“NonWorking”这样:

class NonWorkingSetAttr: 
    def a(self): return 'a'
    def b(self): return 'b'
    def __setattr__(self,a,b): pass

现在我创建对象w和n,然后运行以下命令:

w = WorkingSetAttr()
setattr(w,'a',w.b)
print "w.a = %s, w.b = %s" % (w.a(), w.b())

n = NonWorkingSetAttr()
setattr(n, 'a', n.b)
print "n.a = %s, n.b = %s" % (n.a(), n.b())

输出结果为:

w.a = b, w.b = b
n.a = a, n.b = b

请注意,n.a应打印“b”,但它会打印“a”,因为setattr不会更改属性。

问题是:我应该如何修改对象 n,使其像对象 w一样工作。请注意,我的意思是对象,而不是类。

1 个答案:

答案 0 :(得分:1)

您只需从类对象中删除自定义__setattr__即可。

>>> n = NonWorkingSetAttr()
>>> setattr(n, 'a', n.b)
>>> print("n.a = %s, n.b = %s" % (n.a(), n.b()))
n.a = a, n.b = b
>>> 
>>> del NonWorkingSetAttr.__setattr__
>>>
>>> setattr(n, 'a', n.b)
>>> print("n.a = %s, n.b = %s" % (n.a(), n.b()))
n.a = b, n.b = b

请注意,这会修改,而不是对象。你(几乎可以肯定)不想修改对象本身,因为那时你有一个看起来应该是NonWorkingSetAttr的对象,但实际上是某种你并不真正理解的动态东西。

如果你不能修改类,你可以创建一个子类并用__setattr__重写object

>>> class FixedNonWorkingSetAttr(NonWorkingSetAttr):
...     __setattr__ = object.__setattr__
... 
>>> n = FixedNonWorkingSetAttr()
>>> setattr(n, 'a', n.b)
>>> print("n.a = %s, n.b = %s" % (n.a(), n.b()))
n.a = b, n.b = b
>>> isinstance(n, NonWorkingSetAttr)
True