2014-05-01 28 views
0

有什麼方法可以使用函數調用而不是「a.x = value」語法在Python中設置屬性?使用函數調用設置Python屬性

說明: 有一個我沒有寫的類。我必須從這個類中查詢和設置各種數據。大多數項目具有setter和getter函數,如getA()和setA(value)。但有一些項目已被宣佈爲屬性。我有一些代碼,我得到各種項目的setter函數,以便我可以循環它們。但它不適用於屬性,因爲沒有setter函數。

class DataObject(object): 
    def __init__(self, data, setterFunc): 
     super(DataObject, self).__init__() 
     self._data = data 
     self._setterFunc = setterFunc 

    @property 
    def data(self): 
     return self._data 

    @data.setter 
    def data(self, value): 
     if self._setterFunc: 
      self._data = value 
      self._setterFunc(value) 

foo = SomeClassIDidNotWrite() 
objectList = [] 
objectList.append(DataObject(foo.getA(), foo.setA)) 
objectList.append(DataObject(foo.getB(), foo.setB)) 
# objectList.append(DataObject(foo.c, foo.c)) <-- This does not work 

for dataObj in objectList: 
    dataObj.data = 5 

回答

3

您可以使用setattr()函數動態設置屬性;這也適用於真正屬性的屬性。

您可以創建一個二傳手lambda功能或functools.partial()

objectList.append(DataObject(foo.c, lambda val: setattr(foo, 'c', val))) 

from functools import partial 

objectList.append(DataObject(foo.c, partial(setattr, foo, 'c'))) 
+0

這對我的使用情況非常合適。謝謝。 –

1

@MartijnPieters回答是去,如果有可能的方式,但如果你需要嘗試動態派生設置器,您也可以直接訪問該類的屬性描述符,將該實例作爲參數提供。

foo = SomeClassIDidNotWrite() 
SomeClassIDidNotWrite.a.fset(foo, val) 

甚至更​​多動態:

attr_name = 'a' 
getattr(foo.__class__, attr_name).fset(foo, val) 

與您現有的get/set代碼/結合這一點,並在嘗試包裹它,除非,你可以爲你工作需要的所有屬性創建一個通用的處理程序用。

for attr_name in ('A', 'B', 'C'): 
    try: 
     getter = getattr(foo, 'get' + attr_name) 
     setter = getattr(foo, 'set' + attr_name) 
    except AttributeError: 
     descriptor = getattr(foo.__class__, attr_name) 
     getter = functools.partial(descriptor.fget, foo) 
     setter = functools.partial(descriptor.fset, foo) 
    objectList.append(DataObject(getter, setter)) 
+0

有趣。我不需要爲我的具體情況得到這個通用的,但我不知道這樣的事情是可能的。 –