A classmethod
對象是描述符。你需要了解描述符是如何工作的。
概括地說,描述符是具有方法__get__
,它有三個參數的對象: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'
A classmethod
對象的工作方式相同。當它被擡起時,它的__get__
方法被調用。類方法的__get__
丟棄對應於instance
(如果有的話)的參數,並且當它在包裝的函數上調用__get__
時僅傳遞instance_type
。
一個說明性的塗鴉:
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'
我對「缺少」'__name__'沒有深入的瞭解,但要確保類方法有一個'__call__'包裝。 – mjv 2009-11-05 00:29:14