2012-09-13 136 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__)