我想将一些数据描述符作为类的一部分。这意味着我希望类属性实际上是属性,其访问由类方法处理。
看来Python不直接支持这个,但是可以通过继承type
类来实现。因此,将属性添加到 的子类type
将导致其实例具有该属性的描述符。它的实例是类。因此,类描述符。
这是可取的吗?有什么我应该注意的问题吗?
我想将一些数据描述符作为类的一部分。这意味着我希望类属性实际上是属性,其访问由类方法处理。
看来Python不直接支持这个,但是可以通过继承type
类来实现。因此,将属性添加到 的子类type
将导致其实例具有该属性的描述符。它的实例是类。因此,类描述符。
这是可取的吗?有什么我应该注意的问题吗?
这就是“类属性实际上是属性,其访问由类方法处理”的意思吗?
您可以使用装饰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
当在类上访问描述符时,通常(通常)会返回描述符对象本身。这就是这样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 社区所反对。