首页 > 解决方案 > 为什么在作为另一个类的实例的属性上调用 __setattr__

问题描述

我对试图设置一个类属性而被调用的事实感到非常困惑,该__setattr__属性已经设置为另一个类的实例。考虑以下代码:

class A:
    def __init__(self):
        self.a = 42

    def __add__(self, value):
        print("Incrementing a of A by {}".format(value))
        self.a += value


class B:
    def __init__(self):
        self.a = A()
        self.b = 10

    def __setattr__(self, attr, value):
        print("Setting {} of B to {}".format(attr, value))
        super(B, self).__setattr__(attr, value)


b = B()
print(b.b)
print(b.a)
b.b = 11
b.a += 1
print(b.b)
print(b.a)

运行时,上面的代码会产生以下输出:

Setting a of B to <__main__.A object at 0x7f5e25438410>
Setting b of B to 10
10
<__main__.A object at 0x7f5e25438410>
Setting b of B to 11
Incrementing a of A by 1
Setting a of B to None
11
None

显然,b.a正确查找并递增。但是,在成功查找之后,Python 正在尝试创建一个新属性bcalled a。为什么会这样?

标签: python-3.x

解决方案


根据 Jan Willems 的评论回答我自己的问题:

尽管不明显,但返回解决了所描述的问题__add__(self, value)self该方法的文档(__add__Documentation)没有提到__add__它成功时应该返回任何东西,这就是我的困惑的根源。


推荐阅读