我有一个定义自己的类,__getattr__()
以便与实例化对象包含的 XML 树进行交互。这对用户隐藏了 XML 结构,并允许他设置标签值等,就好像它们是对象上的普通字段一样,并且适用于所有字段,除了一个:名为field
. 这是它的外观:
>>> q = MyQuery()
>>> q.file = "database"
>>> print(q)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<requestCollection xmlns="http://dwd.de/sky">
<read>
<select>
<referenceDate>
<value></value>
</referenceDate>
</select>
<transfer>
<file name="my file"/>
</transfer>
</read>
</requestCollection>
>>> q.file
效果很好,应该发生的副作用就是这样做的。但是如果我尝试设置 field field
,我会得到一个方法不应该返回的字符串。为清楚起见,这是 my 的简化版本__getattr__
:
def __getattr__(self, key):
logging.info("Looking up value for key {}.".format(key))
if key == "something"
return self.method_with_side_effect(key)
if key in field_list:
logging.info("Key is in the field list.")
return self.other_method_with_side_effects(key)
ensemble_member
并且field
都在field_list
. 看一下这个:
>>> q = MyQuery()
>>> q.ensemble_member
Looking up value for key __members__.
Looking up value for key __methods__.
Looking up value for key ensemble_member.
Key is in the field list.
... Side effects ...
>>> q.field
'station'
Looking up value for key __members__.
Looking up value for key __methods__.
for 的行为ensemble_member
是正确field
的,因为它完全不正确。这是为什么?
我没有方法,也没有名为field
.
另一个有趣的事情是,如果我把它放在第一行__getattr__
:
def __getattr__(self, key):
if key == "field":
raise ValueError
仍然会发生以下情况:
>>> q = MyQuery()
>>> q.field
'station'
Looking up value for key __members__.
Looking up value for key __methods__.
这是怎么回事?