Pythonでは、_@classmethod
_デコレータを使用してクラスメソッドを作成できます。
_>>> class C:
... @classmethod
... def f(cls):
... print(f'f called with cls={cls}')
...
>>> C.f()
f called with cls=<class '__main__.C'>
_
または、メタクラスで通常の(インスタンス)メソッドを使用することもできます。
_>>> class M(type):
... def f(cls):
... print(f'f called with cls={cls}')
...
>>> class C(metaclass=M):
... pass
...
>>> C.f()
f called with cls=<class '__main__.C'>
_
C.f()
の出力が示すように、これらの2つのアプローチは同様の機能を提供します。
_@classmethod
_の使用とメタクラスでの通常のメソッドの使用の違いは何ですか?
あなたの例では、違いは、メタクラスとしてMが設定される他のいくつかのクラスにあります。
class M(type):
def f(cls):
pass
class C(metaclass=M):
pass
class C2(metaclass=M):
pass
C.f()
C2.f()
class M(type):
pass
class C(metaclass=M):
@classmethod
def f(cls):
pass
class C2(metaclass=M):
pass
C.f()
# C2 does not have 'f'
ここにメタクラスの詳細があります メタクラスのいくつかの(具体的な)ユースケースは何ですか?
@classmethodとMetaclassはどちらも異なります。
pythonのすべてがオブジェクトです。すべてのものはすべてのものを意味します。
言ったようにすべてのものはオブジェクトです。クラスはオブジェクトでもあり、実際にはクラスは正式にメタクラスと呼ばれる他の不思議なオブジェクトのインスタンスです。指定されていない場合、pythonのデフォルトのメタクラスは「タイプ」です
デフォルトでは、定義されたすべてのクラスはタイプのインスタンスです。
クラスはメタクラスのインスタンスです
言及された行動を理解することはほとんど重要ではありません
次のコードを検討する
class Meta(type):
def foo(self):
print(f'foo is called self={self}')
print('{} is instance of {}: {}'.format(self, Meta, isinstance(self, Meta)))
class C(metaclass=Meta):
pass
C.foo()
どこ、
「クラスC」が「クラスメタ」のインスタンスであるかのように確認できます。
isinstance(C, Meta)
Pythonメソッドはバインドされていると言われています。 pythonは、メソッドをインスタンスのみで呼び出す必要があるという制限を課します。インスタンスを作成せずに、インスタンスなしで(Javaの静的メンバーのように)クラスから直接メソッドを呼び出す場合があります。任意のインスタンス。デフォルトでは、メソッドを呼び出すにはインスタンスが必要です。回避策としてpythonは、インスタンスの代わりにクラスに特定のメソッドをバインドする組み込み関数classmethodを提供します。
クラスメソッドはクラスにバインドされているため。インスタンス(自己)ではなくクラス自体への参照である少なくとも1つの引数を取ります
組み込み関数/デコレータクラスメソッドが使用されている場合。最初の引数はインスタンスではなくクラスへの参照になります
class ClassMethodDemo:
@classmethod
def foo(cls):
print(f'cls is ClassMethodDemo: {cls is ClassMethodDemo}')
「classmethod」を使用したので、次のようにインスタンスを作成せずにメソッド「foo」を呼び出します
ClassMethodDemo.foo()
上記のメソッド呼び出しはTrueを返します。最初の引数clsは確かに「ClassMethodDemo」への参照であるため
概要: