在类方法上使用 property() [英] Using property() on classmethods
问题描述
我有一个包含两个类方法(使用 classmethod()
函数)的类,用于获取和设置本质上是静态变量的内容.我尝试将 property()
函数与这些一起使用,但会导致错误.我能够在解释器中使用以下内容重现错误:
class Foo(object):_var = 5@类方法def getvar(cls):返回 cls._var@类方法def setvar(cls, value):cls._var = 值var = 属性(getvar,setvar)
我可以演示类方法,但它们不能用作属性:
<预><代码>>>>f = Foo()>>>f.getvar()5>>>f.setvar(4)>>>f.getvar()4>>>变量回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 ?类型错误:classmethod"对象不可调用>>>f.var=5回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 ?类型错误:classmethod"对象不可调用是否可以将 property()
函数与 @classmethod
修饰函数一起使用?
Python >= 3.9
只需将两个装饰器一起使用即可.请参阅此答案.
Python <3.9
属性是在类上创建的,但会影响实例.因此,如果您想要一个 classmethod 属性,请在元类上创建该属性.
<预><代码>>>>类 foo(对象):... _var = 5... class __metaclass__(type): # 元类的 Python 2 语法... 经过... @classmethod... def getvar(cls):...返回 cls._var... @classmethod... def setvar(cls, value):... cls._var = 值...>>>foo.__metaclass__.var = property(foo.getvar.im_func, foo.setvar.im_func)>>>变量5>>>foo.var = 3>>>变量3但是由于您无论如何都在使用元类,如果您只是将类方法移到那里,它会读起来更好.
<预><代码>>>>类 foo(对象):... _var = 5... class __metaclass__(type): # 元类的 Python 2 语法... @财产... def var(cls):...返回 cls._var... @var.setter... def var(cls, value):... cls._var = 值...>>>变量5>>>foo.var = 3>>>变量3或者,使用 Python 3 的 metaclass=...
语法,在 foo
类主体之外定义的元类,以及负责设置初始值的元类_var
:
I have a class with two class methods (using the classmethod()
function) for getting and setting what is essentially a static variable. I tried to use the property()
function with these, but it results in an error. I was able to reproduce the error with the following in the interpreter:
class Foo(object):
_var = 5
@classmethod
def getvar(cls):
return cls._var
@classmethod
def setvar(cls, value):
cls._var = value
var = property(getvar, setvar)
I can demonstrate the class methods, but they don't work as properties:
>>> 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
Is it possible to use the property()
function with @classmethod
decorated functions?
Python >= 3.9
Just use both decorators together. See this answer.
Python < 3.9
A property is created on a class but affects an instance. So if you want a classmethod property, create the property on the metaclass.
>>> 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
But since you're using a metaclass anyway, it will read better if you just move the classmethods in there.
>>> 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
or, using Python 3's metaclass=...
syntax, and the metaclass defined outside of the foo
class body, and the metaclass responsible for setting the initial value of _var
:
>>> 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
这篇关于在类方法上使用 property()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!