5

我在分配赋值运算符时遇到问题。

我已经成功重载__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
4

2 回答 2

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()
于 2013-04-24T22:23:16.957 回答
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)
于 2013-04-24T22:21:07.420 回答