<p>阅读<a href="http://www.python.org/download/releases/2.2/descrintro/#property" rel="nofollow noreferrer">Python 2.2 release</a>注释,我发现以下内容。</p>
<blockquote>
<p>The get method [of a property] won't be called when
the property is accessed as a class
attribute (C.x) instead of as an
instance attribute (C().x). If you
want to override the __get__ operation
for properties when used as a class
attribute, you can subclass property -
it is a new-style type itself - to
extend its __get__ method, or you can
define a descriptor type from scratch
by creating a new-style class that
defines __get__, __set__ and
__delete__ methods.</p>
</blockquote>
<p><strong>注意:下面的方法实际上不适用于setter,只适用于getter。</strong></p>
<p>因此,我认为指定的解决方案是创建一个类属性作为属性的子类。</p>
<pre><code>class ClassProperty(property):
def __get__(self, cls, owner):
return self.fget.__get__(None, owner)()
class foo(object):
_var=5
def getvar(cls):
return cls._var
getvar=classmethod(getvar)
def setvar(cls,value):
cls._var=value
setvar=classmethod(setvar)
var=ClassProperty(getvar,setvar)
assert foo.getvar() == 5
foo.setvar(4)
assert foo.getvar() == 4
assert foo.var == 4
foo.var = 3
assert foo.var == 3
</code></pre>
<p>然而,设置器实际上并不起作用:</p>
<pre><code>foo.var = 4
assert foo.var == foo._var # raises AssertionError
</code></pre>
<p><code>foo._var</code>没有改变,您只是用一个新值覆盖了属性。</p>
<p>您还可以使用<code>ClassProperty</code>作为装饰:</p>
<pre><code>class foo(object):
_var = 5
@ClassProperty
@classmethod
def var(cls):
return cls._var
@var.setter
@classmethod
def var(cls, value):
cls._var = value
assert foo.var == 5
</code></pre>