我在分配赋值运算符时遇到了问题。
我已成功重载__setattr__
。但是在初始化对象之后,我希望__setattr__
做其他事情,所以我尝试将其指定为另一个函数__setattr2__
。
代码:
class C(object):
def __init__(self):
self.x = 0
self.__setattr__ = self.__setattr2__
def __setattr__(self, name, value):
print "first, setting", name
object.__setattr__(self, name, value)
def __setattr2__(self, name, value):
print "second, setting", name
object.__setattr__(self, name, value)
c = C()
c.x = 1
我得到了什么:
first, setting x
first, setting __setattr__
first, setting x
我想要/期望的是什么:
first, setting x
first, setting __setattr__
second, setting x
答案 0 :(得分:8)
新式类的特殊方法查找
对于新式类,特殊方法的隐式调用是 只保证在对象的类型上定义时才能正常工作,而不是 在对象的实例字典中。这种行为就是原因所在 以下代码引发异常(与等效示例不同) 与旧式课程):
>>> class C(object): ... pass ... >>> c = C() >>> c.__len__ = lambda: 5 >>> len(c) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'C' has no len()
答案 1 :(得分:3)
为什么不使用标志来表示__init__
仍在进行中?
class C(object):
def __init__(self):
# Use the superclass's __setattr__ because we've overridden our own.
super(C, self).__setattr__('initialising', True)
self.x = 0
# the very last thing we do in __init__ is indicate that it's finished
super(C, self).__setattr__('initialising', False)
def __setattr__(self, name, value):
if self.initialising:
print "during __init__, setting", name
# I happen to like super() rather than explicitly naming the superclass
super(C, self).__setattr__(name, value)
else:
print "after __init__, setting", name
super(C, self).__setattr__(name, value)