classmethod
オブジェクトは記述子です。記述子がどのように機能するかを理解する必要があります。
一言で言えば、記述子は、、、、およびの__get__
3つの引数を取るself
メソッドを持つオブジェクトです。instance
instance type
通常の属性ルックアップ中に、ルックアップされたオブジェクトA
にメソッドがある場合__get__
、そのメソッドが呼び出され、返されるものがオブジェクトの代わりに置き換えられますA
。これは、オブジェクトでメソッドを呼び出すときに、関数(記述子でもある)がバインドされたメソッドになる方法です。
class Foo(object):
def bar(self, arg1, arg2):
print arg1, arg2
foo = Foo()
# this:
foo.bar(1,2) # prints '1 2'
# does about the same thing as this:
Foo.__dict__['bar'].__get__(foo, type(foo))(1,2) # prints '1 2'
classmethod
オブジェクトは同じように機能します。ルックアップされると、その__get__
メソッドが呼び出されます。クラスメソッドの__get__
は、(存在する場合)に対応する引数を破棄し、ラップされた関数を呼び出すときにinstance
のみ渡されます。instance_type
__get__
実例となるDoodle:
In [14]: def foo(cls):
....: print cls
....:
In [15]: classmethod(foo)
Out[15]: <classmethod object at 0x756e50>
In [16]: cm = classmethod(foo)
In [17]: cm.__get__(None, dict)
Out[17]: <bound method type.foo of <type 'dict'>>
In [18]: cm.__get__(None, dict)()
<type 'dict'>
In [19]: cm.__get__({}, dict)
Out[19]: <bound method type.foo of <type 'dict'>>
In [20]: cm.__get__({}, dict)()
<type 'dict'>
In [21]: cm.__get__("Some bogus unused string", dict)()
<type 'dict'>
記述子の詳細については、ここ(他の場所の中でも)を参照してください:http:
//users.rcn.com/python/download/Descriptor.htm
でラップされた関数の名前を取得する特定のタスクの場合classmethod
:
In [29]: cm.__get__(None, dict).im_func.__name__
Out[29]: 'foo'