首页 > 解决方案 > __setattr__ 和 __getattribute__ 在 Python 中如何交互?

问题描述

class Test():
    def __init__(self,age):
        self.age=age
    def __getattribute__(self,attribute):
        print("Initializing getattribute")
        return 6
    def __setattr__(self,attribute,value):
        print("Initializing setattr")
        return object.__setattr__(self,attribute,value)
test=Test(4)
test.age
print(test.age)

从上面的代码结果是:

Initializing setattr
Initializing getattribute
Initializing getattribute
6

我知道每个 dunder 方法在哪里被调用,但它们真正做了什么?在前面的示例中,getattribute 指示属性值,如果我删除该行:

return object.__setattr__(self,attribute,value)

没有什么变化。

那么做__setattr__什么呢?

标签: pythonclassmethods

解决方案


__getattribute__在任何其他尝试访问属性之前调用。不管做什么__setattr__test.age都由 处理test.__getattribute__("age"),它返回6是否有一个名为 的属性age

如果你摆脱__getattribute__

class Test():
    def __init__(self,age):
        self.age=age
    def __setattr__(self,attribute,value):
        print("Initializing setattr")
        return object.__setattr__(self,attribute,value)

test=Test(4)
test.age
print(test.age)

该类行为正常,设置test.age为 4。如果您进一步摆脱对 的调用object.__setattr__,那么您将得到一个AttributeError因为self.age = age将永远不会实际创建或设置age属性;它只是打印初始化消息并返回:

class Test():
    def __init__(self,age):
        self.age=age
    def __setattr__(self,attribute,value):
        print("Initializing setattr")

test=Test(4)
test.age
print(test.age)

结果是

Initializing setattr
Traceback (most recent call last):
  File "/Users/chepner/tmp.py", line 11, in <module>
    test.age
AttributeError: 'Test' object has no attribute 'age'

推荐阅读