2012-09-13 9 views
17

私のクラスの1つでは、取得と設定で非常によく似たプロパティを持っています。だから私は、工場出荷時の関数にpropertyに引数を抽象化:Pythonの `property`をサブクラス化する

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__) 
関連する問題