在Python中分配(或重新重载)赋值运算符时遇到问题

在Python中分配(或重新重载)赋值运算符时遇到问题,python,Python,分配赋值运算符时遇到问题 我已成功地重载\uuuuu setattr\uuuuuu。但是在初始化对象之后,我希望\uuuuu setattr\uuuuuu执行其他操作,因此我尝试将其分配给另一个函数,\uuuuuu setattr2\uuuu 代码: 我得到的是: first, setting x first, setting __setattr__ first, setting x 我想要/期望的: first, setting x first, setting __setattr__ se

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

我已成功地重载
\uuuuu setattr\uuuuuu
。但是在初始化对象之后,我希望
\uuuuu setattr\uuuuuu
执行其他操作,因此我尝试将其分配给另一个函数,
\uuuuuu setattr2\uuuu

代码:

我得到的是:

first, setting x
first, setting __setattr__
first, setting x
我想要/期望的:

first, setting x
first, setting __setattr__
second, setting x

为什么不使用一个标志来指示
\uuuuu init\uuuu
仍在进行中

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)
:

新样式类的特殊方法查找 对于新样式的类,特殊方法的隐式调用是必需的 只有在对象的类型上定义时才能保证正常工作,而不是 在对象的实例字典中。这种行为就是原因 以下代码引发了一个异常(与等效示例不同 (与旧式课程一起):

>>C类(对象):
...     通过
...
>>>c=c()
>>>c.。__len__;=λ:5
>>>莱恩(c)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:类型“C”的对象没有len()

+1.我知道该行为存在,但在文档中找不到相关参考。关于我为什么不能这样做的答案很好。我唯一不明白的是,首先我用旧式类(通过
self.\uu dict\uuuu[name]=value
赋值)尝试了它,但它也不起作用。@chappy:C类中的旧式:而不是
C类(对象):
?是的,也是这样。(除了使用
\uuuuu dict\uuuuu
进行作业外)非常好的解决方法,谢谢。然而,我不得不使用一种变通方法,这一事实让我怀疑我应该用另一种方式解决更普遍的问题。但同时我会用这个@查皮:我完全同意“我应该用另一种方式解决我更普遍的问题”。在
\uuuu dict\uuuu
中翻找时,我总是感到局促不安。在我看来,每当一个人觉得需要
\uuuu setattr\uuuuu
时,通常都可以通过更细粒度的或(或只是策略的一般性更改)来完成这项工作。你最初的想法看起来也是一个解决办法!
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)
>>> 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()