8

Python で classmethod オブジェクトがどのように機能するか、特にメタクラスのコンテキストと__new__. members私の特別なケースでは、に与えられたを反復処理するときに、クラスメソッドメンバーの名前を取得したいと思い__new__ます。

通常のメソッドの場合、名前は単純に__name__属性に格納されますが、クラスメソッドの場合、そのような属性はないようです。__call__属性も存在しないため、クラスメソッドがどのように呼び出されるかさえわかりません。

クラスメソッドがどのように機能するかを説明したり、ドキュメントを教えてもらえますか? グーグルは私をどこにも連れて行かなかった。ありがとう!

4

1 に答える 1

21

classmethodオブジェクトは記述子です。記述子がどのように機能するかを理解する必要があります。

一言で言えば、記述子は、、、、およびの__get__3つの引数を取るselfメソッドを持つオブジェクトです。instanceinstance 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'
于 2009-11-05T00:49:11.777 に答える