python - 默认情况下具有类属性的奇怪 getattr() 行为
问题描述
在这里,我希望所有 4 个 ID 都相同,但是似乎当我将类属性传递给 的default
属性时getattr
,它只是跳过了属性查找并始终返回default
:
Python 3.6.5 (default, May 11 2018, 04:00:52)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from datetime import datetime
...:
...: class my_cls(object):
...: @property
...: def _id(self):
...: self._cid = datetime.now().isoformat()
...: return self._cid
...:
...: def get_id(self):
...: return getattr(self, '_cid', self._id)
...:
...: cls = my_cls()
...: print('Init ID:', cls._id)
...: print('Still OK:', getattr(cls, '_cid', False))
...: print('WRONG:', getattr(cls, '_cid', cls._id))
...: print('WRONG:', cls.get_id())
...:
...:
Init ID: 2018-06-17T12:45:20.409601
Still OK: 2018-06-17T12:45:20.409601
WRONG: 2018-06-17T12:45:20.409804
WRONG: 2018-06-17T12:45:20.409849
这是预期和/或记录的行为吗?为什么getattr
要做它正在做的事情?
解决方案
不是,这是您在调用之前getattr
访问的代码。cls._id
getattr
在 Python 中,在调用函数之前,会计算其所有参数。特别是,在getattr(cls, '_cid', cls._id)
子表达式cls._id
中求值。为此,_id
访问属性,更新_cid
. getattr
之后调用并返回更新的值。
推荐阅读
- javascript - 当元素获得焦点时停止输入文本
- node.js - 为什么 Redis 进入异步功能太慢了?
- macos - ld:找不到 -lSystem macOS Big Sur 11.1 的库
- bash - 将交互式命令绑定到键序列
- python - 移除对象后移除媒体文件
- c - 用空格和符号扫描一行以分隔条目并使用 C 中的结构
- c# - 为什么将 FormatConvertedBitmap 设置为备用图像源会引发“源”未设置异常?
- python - Django Rest Framework 中的 JWT 和自定义身份验证
- rust - 类型绑定中的特征“未实现”?
- python - 尝试运行 flake8 的 gitlab ci 返回错误:pipenv run flake8