使用字典键访问类属性

时间:2016-04-03 00:30:28

标签: python python-3.x

假设我正在构建一个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__

有哪些替代方案?

1 个答案:

答案 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