通过继承`type`类来实现类描述符

时间:2010-07-18 20:09:01

标签: python class properties class-attributes descriptor

我希望将一些数据描述符作为类的一部分。这意味着我希望类属性实际上是属性,其访问权限由类方法处理。

似乎Python不直接支持这一点,但它可以通过继承type类来实现。因此,向type的子类添加属性将导致其实例具有该属性的描述符。它的实例是类。因此,类描述符。

这是否可取?有什么问题需要注意吗?

2 个答案:

答案 0 :(得分:1)

这是什么意思“类属性实际上是属性,其访问权限由类方法处理”?

您可以使用装饰器property使访问者看起来像是实际的数据成员。然后,您可以使用x.setter装饰器为该属性创建一个setter。

请务必继承object,否则无效。

class Foo(object):
    def __init__(self):
            self._hiddenx = 3
    @property
    def x(self):
            return self._hiddenx + 10
    @x.setter
    def x(self, value):
            self._hiddenx = value

p = Foo()

p.x #13

p.x = 4
p.x #14

答案 1 :(得分:1)

对于描述符,当在类上访问时,返回描述符对象本身是常规(通常)。这就是property的作用;如果您访问类上的属性对象,则会返回属性对象(因为这是__get__方法选择执行的操作)。但这是一个惯例;你没必要这样做。

所以,如果你只需要在你的类上有一个 getter 描述符,并且你不介意设置的尝试将覆盖描述符,你可以做这样的事情,没有元类编程:

def classproperty_getter_only(f):
    class NonDataDescriptor(object):
        def __get__(self, instance, icls):
            return f(icls)
    return NonDataDescriptor()

class Foo(object):

    @classproperty_getter_only
    def flup(cls):
        return 'hello from', cls

print Foo.flup
print Foo().flup

('hello from', <class '__main__.Foo'>)
('hello from', <class '__main__.Foo'>)

如果你想要一个完整的数据描述符,或者想要使用内置的属性对象,那么你就可以使用元类并将它放在那里(意识到这个属性在你的实例中是完全不可见的class;在类的实例上进行属性查找时不检查元类。)

这是可取的吗?我不这么认为。我不会做你在生产代码中随便描述的内容;如果我有一个非常令人信服的理由这样做,我只会考虑它(而且我无法想到这样的情况)。元类非常强大,但是所有程序员都不太了解它们,并且有点难以推理,因此它们的使用会使代码难以维护。我认为这种设计会受到整个python社区的不满。