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

时间:2019-09-18 19:31:03

标签: python python-3.x class operator-overloading

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

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

但是我遇到了这个错误

AttributeError: 'MyClass' object has no attribute 'x'

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

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

1 个答案:

答案 0 :(得分: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'

您看到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