我希望将一些数据描述符作为类的一部分。这意味着我希望类属性实际上是属性,其访问权限由类方法处理。
似乎Python不直接支持这一点,但它可以通过继承type
类来实现。因此,向type
的子类添加属性将导致其实例具有该属性的描述符。它的实例是类。因此,类描述符。
这是否可取?有什么问题需要注意吗?
答案 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社区的不满。