假设我正在构建一个GUI来修改Building
个对象集合的属性:
class Building:
def __init__(self, company, addr):
self.company = company
self.addr = addr
每次在GUI中突出显示新的Building
时,各种小部件都应该更新以反映该对象的属性。
我想将每个Building属性链接到控制它的小部件。也许是这些方面的东西:
attribute_widget_map = {
'company': company_widget,
'addr': addr:widget,
}
所以当我去设置每个小部件的值时,我可以这样做:
building = Building('XYZ', 'Anytown USA')
for attr, widget in attribute_widget_map.items():
widget.set_value(building.__getattr__(attr))
我的问题:我不认为attribute_widget_map
中的键是Building
属性的字符串表示。假设我将addr
更改为address
。代码将破裂。有没有其他方法可以做到这一点,而不是依靠__getattr__
?
有哪些替代方案?
答案 0 :(得分:0)
您可以使用property
装饰器的变体解决此问题:
class Bindings:
def __init__(self):
self.__bindings = []
def bound_to(self, widget):
def inner(func):
prop = property(func)
self.__bindings.append((prop, widget))
return prop
return inner
def __iter__(self):
return iter(self.__bindings)
class Building:
def __init__(self, address):
self._address = address
bindings = Bindings()
@bindings.bound_to("address_widget")
def address(self):
return self._address
@address.setter
def address(self, value):
self._address = value
然后你可以有一个功能:
def update_widgets(building):
for prop, widget in building.bindings:
widget.value = prop.fget(building)
使用以下小部件存根:
>>> class Widget:
... def __init__(self, name):
... self.name = name
... Bindings.boundWidget['address'] = self
... def update(self, value):
... print(self.name, value)
...
-
>>> address_widget = Widget("Address widget")
>>> anySt = Building("123 Any Street")
>>> someAv = Building("42 Some Avenue")
>>>
>>> update_widgets(anySt)
Address widget 123 Any Street
>>> update_widgets(someAv)
Address widget 42 Some Avenue