首页 > 解决方案 > 默认情况下具有类属性的奇怪 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要做它正在做的事情?

标签: pythonpython-3.xgetattr

解决方案


不是,这是您在调用之前getattr访问的代码。cls._idgetattr

在 Python 中,在调用函数之前,会计算其所有参数。特别是,在getattr(cls, '_cid', cls._id)子表达式cls._id中求值。为此,_id访问属性,更新_cid. getattr之后调用并返回更新的值。


推荐阅读