我有一个存储变量的类,然后应该调用能够执行给定的代码片段,作为参数传递,只要该变量更改为指定的值。我想这样做:
class SharedAttribute(object):
def __init__(self, value, onEquals={}):
self.value = value
self.onEquals = onEquals
def __setattr__(self, key, val):
super(SharedAttribute, self).__setattr__(key, val) #Set the attribute to the new value
if key == "value": #If the attribute being changed is the value attribute:
if val in self.onEquals: #If the new value is something that should cause something to happen:
if type(self.onEquals[val]) == str: #If there's only one command:
exec(self.onEquals[val]) #execute it
elif type(self.onEquals[val]) == tuple: #If there's a tuple of commands:
for eachFunction in self.onEquals[value]: #Execute each of them
exec(eachFunction)
它会像这样实例化:
foo = SharedAttribute(0, onEquals = {1: 'doSomething(arguments)', 2: ('doAnotherThing()', 'yetAnotherThing(arguments)'})
当我尝试创建一个类的实例时,它给了我
AttributeError: 'SharedAttribute' object has no attribute 'onEquals'.
我认为这是因为if val in self.onEquals
在定义onEquals
时尝试访问onEquals
,因为它正在调用__setattr__
来定义它,但我添加了if key == "value":
,它仍在表现。怎么了?
答案 0 :(得分:1)
您的问题是__setattr__
中的self.value = value
也被__init__
调用,然后访问尚未定义的self.onEquals
。
您可以按照建议尝试更改self.value
中self.onEquals
和__init__
行的顺序。
但是,如果您不希望在实例化类时从onEquals
运行函数,请保持订单不变,并检查onEquals
是否已在__setattr__
中设置:
def __setattr__(self, key, val):
super(SharedAttribute, self).__setattr__(key, val)
if key == "value" and getattr(self, "onEquals", False):
...
答案 1 :(得分:0)
__setattr__
调用每次访问权限以保存属性。当SharedAttribute
的{{1}}运行时,__init__()
和self.value
都不存在,但self.onEquals
会在设置时__setattr__
尝试访问self.onEquals
self.value
1}} - 因为您先设置self.value
。
所以你有几种不同的方法可以解决这个问题:
__init__
功能中的两行,或onEquals
设置为空dict
第一种解决方案是最快捷,最简单的解决方案;第二种解决方案存在一些风险,即您将无意中访问onEquals
的类版本,然后很难找到错误来解决问题。