1

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

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

这是可取的吗?有什么我应该注意的问题吗?

4

2 回答 2

1

这就是“类属性实际上是属性,其访问由类方法处理”的意思吗?

您可以使用装饰property器使访问器看起来是实际的数据成员。然后,您可以使用x.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
于 2010-07-18T20:15:40.887 回答
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'>)

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

可取吗?我不这么认为。我不会做你在生产代码中随便描述的事情。如果我有一个非常令人信服的理由,我只会考虑它(而且我想不出这样的场景)。元类非常强大,但并不是所有的程序员都能很好地理解它们,而且有点难以推理,所以它们的使用会使你的代码更难维护。我认为这种设计会被整个 python 社区所反对。

于 2010-07-18T21:31:22.190 回答