我有一个带有两个类方法的类(使用classmethod()函数),用于获取和设置本质上是静态变量的东西。我试图将property()函数与这些函数一起使用,但会导致错误。我能够在解释器中使用以下代码重现该错误:
classmethod()
property()
class Foo(object): _var = 5 @classmethod def getvar(cls): return cls._var @classmethod def setvar(cls, value): cls._var = value var = property(getvar, setvar)
我可以演示类方法,但是它们不能用作属性:
>>> f = Foo() >>> f.getvar() 5 >>> f.setvar(4) >>> f.getvar() 4 >>> f.var Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'classmethod' object is not callable >>> f.var=5 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'classmethod' object is not callable
是否可以将property()函数与类方法修饰的函数一起使用?
属性是在类上创建的,但会影响实例。因此,如果要使用classmethod属性,请在元类上创建该属性。
classmethod
>>> class foo(object): ... _var = 5 ... class __metaclass__(type): # Python 2 syntax for metaclasses ... pass ... @classmethod ... def getvar(cls): ... return cls._var ... @classmethod ... def setvar(cls, value): ... cls._var = value ... >>> foo.__metaclass__.var = property(foo.getvar.im_func, foo.setvar.im_func) >>> foo.var 5 >>> foo.var = 3 >>> foo.var 3
但是由于无论如何都使用元类,因此只要将类方法移入其中,它就会更好看。
>>> class foo(object): ... _var = 5 ... class __metaclass__(type): # Python 2 syntax for metaclasses ... @property ... def var(cls): ... return cls._var ... @var.setter ... def var(cls, value): ... cls._var = value ... >>> foo.var 5 >>> foo.var = 3 >>> foo.var 3
或者,使用Python 3的metaclass=...语法,在foo类主体外部定义的元类,以及负责设置初始值的元类_var:
metaclass=...
>>> class foo_meta(type): ... def __init__(cls, *args, **kwargs): ... cls._var = 5 ... @property ... def var(cls): ... return cls._var ... @var.setter ... def var(cls, value): ... cls._var = value ... >>> class foo(metaclass=foo_meta): ... pass ... >>> foo.var 5 >>> foo.var = 3 >>> foo.var 3