我有一个类,它定义了自己的__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
,就会得到一个该方法不应该返回的字符串。为了清楚起见,这是我的__getattr__
的简化版本:
ensemble_member
和{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__.
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__.
怎么回事?
我明白了-冒犯的代码最后是这样的:
在我的列表理解中命名临时变量“field”是导致这个问题的原因。我做完后,Python还保留着它。这种行为是一贯的,我只是没料到。在
我在这里看到了三个解决方案(第三个是由用户4815162342建议的)。我实现了第三个。在
将临时变量重命名为
x
,而不是field
。然后,我仍然将x
作为一个临时变量在我的代码中浮动,但是因为没有成员应该被称为x
,所以我并不介意。调用
del(field)
删除字段。我不喜欢调用del()
,我认为这会使我的代码混乱,但如果我以后真的需要访问该变量,它就可以工作了。将列表理解替换为生成器表达式
list(field + "_value" for field in _unique_fields)
,该表达式不存在此问题相关问题 更多 >
编程相关推荐