classmethod()
本質的に静的変数を取得および設定するための2 つのクラス メソッド (関数を使用) を持つクラスがあります。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
ベストアンサー1
3.8 < Python < 3.11
両方のデコレータを一緒に使用できます。この答え。
Python 2 および Python 3 (3.9-3.10 でも動作します)
プロパティはクラス上に作成されますが、インスタンスに影響します。したがって、プロパティが必要な場合は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
。
>>> 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