classmethod对象如何工作?

nik*_*kow 8 python metaclass class-method

我无法理解classmethod对象在Python中是如何工作的,特别是在元类和in的上下文中__new__.在我的特殊情况下,我想得到一个classmethod成员的名字,当我迭代通过members给予的__new__.

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

有人可以向我解释一下类方法是如何工作的,还是指向一些文档?谷歌搜索引导我无处可去.谢谢!

Mat*_*son 20

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

简而言之,描述符是一个具有方法的对象,该方法__get__有三个参数:self,an instance和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'
Run Code Online (Sandbox Code Playgroud)

一个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'>
Run Code Online (Sandbox Code Playgroud)

有关描述符的更多信息可以在这里找到(在其他地方):http: //users.rcn.com/python/download/Descriptor.htm

对于获取包含的函数名称的具体任务classmethod:

In [29]: cm.__get__(None, dict).im_func.__name__
Out[29]: 'foo'
Run Code Online (Sandbox Code Playgroud)

  • 抱歉,我忘了强调我非常感谢您非常详细的回答,这太棒了。 (2认同)
  • `.im_func` 现在是 python 3 中的 `__func__`。 [来源:2to3](https://docs.python.org/3/library/2to3.html#2to3fixer-methodattrs) (2认同)