为什么我无法在对象的__setattr__方法中获取属性?

rvc*_*and 1 python class operator-overloading python-3.x

我有一个具有某些属性的类,在检查其他属性后可以更改该属性,因此我对此类进行了编码:

class MyClass():
    def __init__(self, x):
        self.x = x

    def __setattr__(self, name, value):
        print(self.x)  # doesn't work

        self.__dict__[name] = value

if __name__ == '__main__':
    myObj = MyClass(1)

    myObj.x = 2
Run Code Online (Sandbox Code Playgroud)

但是我得到这个错误

AttributeError: 'MyClass' object has no attribute 'x'
Run Code Online (Sandbox Code Playgroud)

如果我没有print(self.x)重写的属性,但是我需要检查其他属性以更改另一个属性。

我尝试了self.__dict__[name]getattr(self,name),但是遇到了同样的错误。

Ano*_*ard 5

完整的错误消息是有益的:

Traceback (most recent call last):
  File "example_code.py", line 11, in <module>
    myObj = MyClass(1)
  File "example_code.py", line 3, in __init__
    self.x = x
  File "example_code.py", line 6, in __setattr__
    print(self.x)  # doesn't work
AttributeError: 'MyClass' object has no attribute 'x'
Run Code Online (Sandbox Code Playgroud)

您会看到的初始化错误,该初始化MyClass又调用self.x = x,而后者又调用您的自定义__setattr__实现来完成工作。此时,它正在尝试打印x,但这是在x分配给该类之前的,因为您尚未完成该工作。

有几种方法可以解决此问题,最直接的方法可能是在尝试访问类之前先验证您的类是否确实具有该属性:

class MyClass():
    def __init__(self, x):
        self.x = x

    def __setattr__(self, name, value):
        if hasattr(self, 'x'):
            print(self.x)  # works now

        self.__dict__[name] = value

if __name__ == '__main__':
    myObj = MyClass(1)

    myObj.x = 2
Run Code Online (Sandbox Code Playgroud)