我使用wx库来构建GUI。我初始化了一个面板并初始化了一些按钮,并绑定了一个在推送时执行的功能。该函数接受一个参数列表,一个是回调函数。我想要做的是在运行时重新定义回调函数,但我没有这样做。
到目前为止,我的尝试是:
self.UpdateCurrent = None
self.GetCurrent = None
self.UpdateCellVoltage = None
self.GetCellVoltage = None
self.UpdateCellTemperature = None
self.GetCellTemperature = None
self.battery_control_d = OrderedDict([('Current',[self.UpdateCurrent, self.GetCurrent, None, 1]),
('Cell Voltage',[self.UpdateCellVoltage, self.GetCellVoltage, 0, 24]),
('Cell Temperature',[self.UpdateCellTemperature, self.GetCellTemperature, 0, 24])])
.
.
.
submit_btn_l[-1].Bind(wx.EVT_BUTTON,
lambda evt,
io_name = io_name,
callback_fn = self.battery_control_d[io_name][0],
ctrl_textbox = ctrl_textbox,
dim_combobox = self.dim_combobox_l[-1]:
self._send_control_value(evt,
io_name,
callback_fn,
ctrl_textbox,
dim_combobox))
.
.
.
def init_battery_intf(self):
self.battery_intf = self.simulator_main_panel.battery_intf
self.UpdateCurrent = self.battery_intf.UpdateCurrent
self.GetCurrent = self.battery_intf.GetCurrent
self.UpdateCellVoltage = self.battery_intf.UpdateCellVoltage
self.GetCellVoltage = self.battery_intf.GetCellVoltage
self.UpdateCellTemperature = self.battery_intf.UpdateCellTemperature
self.GetCellTemperature = self.battery_intf.GetCellTemperature
.
.
.
def _send_control_value(self,
evt,
io_name,
callback_fn,
ctrl_textbox,
dim_combobox):
io_value = float(ctrl_textbox.Value)
if ("Temperature" in io_name):
io_value -= self.simulator_main_gui.temperature_unit_converter
callback_fn(io_value, int(dim_combobox.Value))
def update( self,
evt ):
for io_name, io_info in self.battery_control_d.iteritems():
io_value = float(io_info[1](io_info[2]))
self.reading_text_l[self.io_indexer.index(io_name)].SetLabel(" %.4f " % (io_value))
我预定义了一些更新/获取对象。
我将函数绑定到按钮
在运行时,我调用init_battery_intf来初始化这些对象
当我尝试调用回调函数时出错的行。它似乎仍被设置为无。
Traceback (most recent call last):
File "C:\Users\Sam\Desktop\work\simulator\src\simulate.py", line 1185, in updat
self.control_notebook.update(evt)
File "C:\Users\Sam\Desktop\work\simulator\src\simulate.py", line 869, in update
self.battery_control_panel.update(evt)
File "C:\Users\Sam\Desktop\work\simulator\src\simulate.py", line 591, in update
io_value = float(io_info[1](io_info[2]))
TypeError: 'NoneType' object is not callable
我知道我可以重新定义绑定并直接输入值,但我想保持我的代码干净简单,我觉得Python有办法将重新定义的回调函数分发给对象的所有实例。 / p>
我正在使用Python 2.7。
答案 0 :(得分:0)
您有几个选择:
答:self.UpdateCurrent
和self.battery_control_d
使用的其他方法已初始化。 (从不初始化为无)
B:当self.UpdateCurrent
和/或其他人更新时,重新创建/更新self.battery_control_d
。
C:使用名称引用并从self.battery_control_d
访问时获取该属性的值。
前两个是非常自我解释但似乎你对选项C感兴趣所以我会扩展它:
您可以创建一个包含多个property
的类,以便在访问时从原始对象中检索属性。
class VarReference(object):
def __init__(self, inst, update_name, get_name, value1, value2):
self.inst = inst
self.update_attr_name = update_name
self.getter_attr_name = get_name
self.value1 = value1
self.value2 = value2
@property
def get(self):
return getattr(self.inst, self.getter_attr_name)
@property
def update(self):
return getattr(self.inst, self.update_attr_name)
class Test(object):pass #dummy class for my demo
self = Test()
self.UpdateCurrent = self.GetCurrent = None
ref_obj = VarReference(self,"UpdateCurrent","GetCurrent",None,1)
>>> print(ref_obj.get)
None
>>> self.GetCurrent = lambda:5
>>> ref_obj.get
<function <lambda> at 0x1057d5488>
>>> ref_obj.get()
5
如果您不熟悉property
,则在实例上访问属性名称时会调用它所修饰的函数(因此检索原始实例的属性)
所以在这种情况下你会像这样写self.battery_control_d
的初始化:
self.battery_control_d = OrderedDict([('Current',VarReference(self, "UpdateCurrent", "GetCurrent", None, 1)),
('Cell Voltage',VarReference(self, "UpdateCellVoltage", "GetCellVoltage", 0, 24)),
('Cell Temperature',VarReference(self, "UpdateCellTemperature", "GetCellTemperature", 0, 24))
])
然后self.battery_control_d["current"].get
将是getattr(self,"GetCurrent")
的结果,它相当于self.GetCurrent
动态。
如果您真的想使用VALUE[0]
和VALUE[1]
代替VALUE.update
和VALUE.get
,那么您也可以覆盖该类的__getitem__
,尽管我强烈建议切换到更详细的解决方案:
class VarReference(object):
...
def __getitem__(self,item):
if item==0:
return self.update
elif item == 1:
return self.get
elif item ==2:
return self.value1
elif item == 3:
return self.value2
else:
raise IndexError("Can only get indices from 0 to 3")