8

我很难理解 classmethod 对象在 Python 中是如何工作的,尤其是在元类和__new__. 在我的特殊情况下,当我遍历members被赋予的__new__.

对于普通方法,名称只是存储在__name__属性中,但对于类方法,显然没有这样的属性。我什至看不到如何调用类方法,因为也没有__call__属性。

有人可以向我解释一个类方法是如何工作的或指向我一些文档吗?谷歌搜索让我无处可去。谢谢!

4

1 回答 1

21

classmethod对象是描述符。您需要了解描述符的工作原理。

简而言之,描述符是具有方法的对象,该方法__get__接受三个参数:self、 aninstance和 an 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__

一个说明性的涂鸦:

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

对于获取由 a 包裹的函数名称的特定任务classmethod

In [29]: cm.__get__(None, dict).im_func.__name__
Out[29]: 'foo'
于 2009-11-05T00:49:11.777 回答