2016-04-03 33 views
0

假設我建立一個GUI修改Building對象的集合屬性:使用字典的鍵來訪問類屬性

class Building: 

    def __init__(self, company, addr): 
     self.company = company 
     self.addr = addr 

每當一個新的Building在GUI中突出顯示,各種小部件應該更新反映該對象的屬性。

我想將每個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

無論哪種方式,如果你改變一個,你必須改變另一個。沒有? – idjaw

+0

也許我的問題應該是:這是'__getattr__'的適當使用嗎? – Crispin

+0

對我來說這似乎很好。當然,也許有人可能會來和別的什麼人說。但是,對我來說很好。 – idjaw

回答

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) 

使用下面的Widget存根:

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