python - __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__
什么呢?
解决方案
__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'
推荐阅读
- web-scraping - 使用 Rvest 抓取 - 表格只有标题
- c++ - Winapi 创建选项卡菜单
- javafx - 组合框中的 JavaFX 组合框
- postgresql - 在某些情况下,UPDATE 事务是否会失败而不是阻塞等待“FOR UPDATE 锁定”?
- php - 如何在从我的数据库写入和读取时防止并发?
- google-chrome - 如何让 Chrome 网络扩展程序读取 Chrome 设置“下载前询问每个文件的保存位置”?
- spring - 在 JWT 和 Spring 中使用范围限制访问
- javascript - 找不到 React/Node 应用程序的 Node sdk。如何将亚马逊支付与 React 应用程序集成
- angular - 反应形式自定义验证器未在 angular6 中显示错误
- .net - FFMPEG 在线程错误:线程被中止