默认情况下 class 属性 的奇怪 getattr() 行为
Odd getattr() behaviour with class property in the default
这里我希望所有 4 个 ID 都相同,但是似乎当我将 class 属性 传递给 getattr
的 default
属性时,它只是跳过属性查找并始终 return 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
这是预期的 and/or 记录行为吗?为什么 getattr
正在做它正在做的事情?
这不是 getattr
,而是您的代码在调用 getattr
之前访问 cls._id
。
在Python中,在函数被调用之前,它的所有参数都会被求值。特别是,在 getattr(cls, '_cid', cls._id)
中计算子表达式 cls._id
。为此,访问 _id
属性,更新 _cid
。 getattr
之后调用,returns 更新后的值。
这里我希望所有 4 个 ID 都相同,但是似乎当我将 class 属性 传递给 getattr
的 default
属性时,它只是跳过属性查找并始终 return 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
这是预期的 and/or 记录行为吗?为什么 getattr
正在做它正在做的事情?
这不是 getattr
,而是您的代码在调用 getattr
之前访问 cls._id
。
在Python中,在函数被调用之前,它的所有参数都会被求值。特别是,在 getattr(cls, '_cid', cls._id)
中计算子表达式 cls._id
。为此,访问 _id
属性,更新 _cid
。 getattr
之后调用,returns 更新后的值。