【问题标题】:Why I can't fetch an attribute inside object's __setattr__ method?为什么我无法在对象的 __setattr__ 方法中获取属性?
【发布时间】:2019-09-18 19:31:03
【问题描述】:

我有一个类,其属性在检查其他属性后可以更改,所以我编写了这个类:

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(self, name) 但我得到了同样的错误。

【问题讨论】:

  • 我假设__init__ 中的self.x = x 正在运行__setattr__ 方法——毕竟你是在设置一个属性。并且此时对象上确实没有x 属性。
  • @RobinZigmond 点。这应该是一个答案
  • @DeepSpace 公平点,但我只说“我假设”,因为我对自己的 Python 知识没有足够的信心来确定这就是正在发生的事情。 (虽然我大约是 90%)我会留下 AnonCoward 的答案而不添加另一个答案,因为它说的更详细。
  • @RobinZigmond 是的,在我运行它以查看完整错误之前,我已经完成了 90% 的工作。对不起,偷了你的雷,我在检查 cmets 之前写了回复。

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


【解决方案1】:

完整的错误信息提供信息:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-10
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 1970-01-01
    相关资源
    最近更新 更多