python中的描述符

一般的得到一个类或是一个实例的属性的方法是从类或是实例的__dict__中查找。这样属性
可以做的事情会因为这种方式而得到限制(他们仅仅是一个data,或是第一个默认参数是所属
实例的方法)。为了提供更大的弹性,就有了描述符descriptors。

在这种体制中,主类(owner class)有方法是描述符定义的。

他们定义了三个接口:
__get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance)
instance是owner class的一个实例,owner是owner class名。

如果实现了__get__和__set__就是一个data描述符,如果只有__get__就是一个non-data
描述符。不同的效果在于data描述符总是替代在一个实例中的实现,而non-data描述符可以
在实例中改变。当然如果仅仅在__set__中raise AttributeError,仍然得到的是一个
non-data的描述符。

几个python中自建的方法的利用描述符体制的python实现。
property:
class Property(object):
    def __init__(self, get=None, set=None, del=None, doc=None):
        self.get = get
        self.set = set
        self.del = del
        self.__doc__ = doc
    def __get__(self, obj, klass=None):
        if obj is None:
            return self
        if self.get is None:
            raise AttributeError
        return self.get(obj)
    def __set__(self, obj, value):
        if self.set is None:
            raise AttributeError
        self.set(obj, value)
    def __delete__(self, obj):
        if self.del is None:
            raise AttributeError
        self.del(obj)
staticmethod:
class StaticMethod(object):
    def __init__(self, f):
        self.f = f
    def __get__(self, obj, klass=None):
        return self.f
classmethod:
class ClassMethod(object):
    def __init__(self, f):
        self.f = f
    def __get__(self, obj, klass=None):
        if klass is None:
            klass = type(obj)
        def newfunc(*args):
            return self.f(klass, *args)
        return newfunc