2012-09-13 180 views
17

在我的一個類中,我有許多屬性在獲取和設置方面做了非常類似的事情。所以,我抽象的參數property到工廠功能:繼承Python的`屬性`

def property_args(name): 
    def getter(self): 
     # do something 
     return getattr(self, '_' + name) 
    def setter(self, value) 
     # do something 
     setattr(self, '_' + name, value) 
    return getter, setter 

class MyClass(object): 
    def __init__(self): 
     self._x = None 
    x = property(*property_args('x')) # obviously there's more than one of these IRL 

但是,因爲我已經發現property實際上是一個類,繼承它會爲這個完美的。我在文檔中找不到任何解釋我需要重寫的內容(以及__init__等的參數簽名),並且我並不想在C源代碼中尋找它。有誰知道我在哪裏可以找到這些信息?

+1

作爲參考,C實現可以在這裏找到:http://hg.python.org/cpython/file/tip/Objects/descrobject.c – nneonneo

+0

@nneonneo:謝謝!第1228行的大評論塊就是答案。如果你想在完整的答案中寫出這個,那麼我會接受它。 –

+0

poorsod你可以回答你自己的問題:) –

回答

18

這裏是一個純Python等效的代碼財產()

class Property(object): 
    "Emulate PyProperty_Type() in Objects/descrobject.c" 

    def __init__(self, fget=None, fset=None, fdel=None, doc=None): 
     self.fget = fget 
     self.fset = fset 
     self.fdel = fdel 
     if doc is None and fget is not None: 
      doc = fget.__doc__ 
     self.__doc__ = doc 

    def __get__(self, obj, objtype=None): 
     if obj is None: 
      return self 
     if self.fget is None: 
      raise AttributeError("unreadable attribute") 
     return self.fget(obj) 

    def __set__(self, obj, value): 
     if self.fset is None: 
      raise AttributeError("can't set attribute") 
     self.fset(obj, value) 

    def __delete__(self, obj): 
     if self.fdel is None: 
      raise AttributeError("can't delete attribute") 
     self.fdel(obj) 

    def getter(self, fget): 
     return type(self)(fget, self.fset, self.fdel, self.__doc__) 

    def setter(self, fset): 
     return type(self)(self.fget, fset, self.fdel, self.__doc__) 

    def deleter(self, fdel): 
     return type(self)(self.fget, self.fset, fdel, self.__doc__)