"ユーザ"の観点から見ると、Pythonのクラスメソッドは、最初のパラメータとしてクラスのインスタンスを受け取る「通常の」メソッドとは異なり、そのクラスを最初のパラメータとして受け取るメソッドです。 self
と呼ばれます。
そのクラスのインスタンスではなく、クラスから「通常の」メソッドを取得すると、関数のラッパーであるオブジェクトが自動的に追加されないクラス自体、または呼び出されたときの最初のパラメータとしてのインスタンスのいずれかです。したがって、「バインドされていないメソッド」を呼び出す場合は、そのクラスのインスタンスを最初のパラメータとして手動で渡す必要があります。手動でクラスメソッドを呼び出した場合、他の一方で、クラスはあなたのための最初のパラメータとして記入されて
:多かれ少なかれ、このようなものです何が起こるのか、フードの下
>>> class A(object):
... def b(self):
... pass
... @classmethod
... def c(cls):
... pass
...
>>> A.b
<unbound method A.b>
>>> A.c
<bound method type.c of <class '__main__.A'>>
>>> A.c()
>>> A.b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method b() must be called with A instance as first argument (got nothing instead)
>>>
- 」で新しいスタイルクラス ":
クラス本体を定義するとき、メソッドは単なる普通の関数です - クラス本体が終了すると、Pythonはクラスのメタクラス(通常は組み込みのtype
)を呼び出し、パラメータとして渡します名前、基本クラス、およびクラス本体の辞書。この呼び出しはクラスを生成します。これは、Pythonではオブジェクトであるため、クラスです。
ここで、Pythonには属性アクセスをカスタマイズするための素晴らしい方法がいくつかあります。いわゆる「記述子」です。記述子は、__get__
という名前のメソッド(または__set__
または__del__
)を定義するオブジェクトですが、ここではそれらは気にしません。 Pythonでクラスまたはオブジェクトの属性にアクセスすると、その属性によって参照されるオブジェクトが返されます(クラス属性であり、オブジェクトが記述子である場合を除く)。その場合、オブジェクト自体を返す代わりに、Pythonはそのオブジェクトに対して__get__
メソッドを呼び出し、代わりにその結果を返します。たとえば、property
ビルトインは、__set__
,__get__
および__del__
の両方を適切に実装するクラスに過ぎません。
ここで、属性が取得されたとき、その本体上の関数(またはデータモデルの状態としてのクラスメソッドまたは非バインドメソッド)が__get__
メソッドを持ち、それが記述子になります。基本的には、各属性で、関数本体で定義されている関数として名前を付けられたオブジェクトを取得するためのアクセス権が、その関数の周りに新しいオブジェクトを作成する記述子 - 呼び出されると最初のパラメータが自動的に埋め込まれるオブジェクト - 例えば、method
です。
例:
>>> class B(object):
... def c(self):
... pass
... print c
...
<function c at 0x1927398>
>>> print B.c
<unbound method B.c>
>>> b = B()
>>> b.c
<bound method B.c of <__main__.B object at 0x1930a10>
あなたは関数オブジェクトを取得する場合、メソッドオブジェクトに変換せずに、あなたが記述をトリガしませんクラスの__dict__
属性を介して、そうすることができます。
>>> B.__dict__["c"]
<function c at 0x1927398>
>>> B.__dict__["c"].__get__
<method-wrapper '__get__' of function object at 0x1927398>
>>> B.__dict__["c"].__get__(b, B)
<bound method B.c of <__main__.B object at 0x1930a10>>
>>> B.__dict__["c"].__get__(None, B)
<unbound method B.c>
「クラスメソッド」は、組み込み関数で明示的に装飾された異なるタイプのオブジェクトですclassmethod
- __get__
が呼び出されたときに返されるオブジェクトは、origiコール時に最初のパラメータとしてcls
を入力する関数です。
したがって、バインドされていないメソッドを「インスタンスのメソッド」とし、クラスメソッドを「クラスのメソッド」とします。 – Determinant
つまり、クラスから直接バインドされていないメソッドを呼び出すと、このメソッドを呼び出すには、最初にオブジェクトを作成してからメソッド "from"オブジェクトを呼び出す必要があります。クラスから直接メソッドを呼び出す場合は、デコレータ@staticmethodを使用してください。 – Denis
@Denisよく装飾されたメソッド'@ classmethod'を使って、クラスへのバインドメソッドと言うことができますか? – Determinant