类方法对象如何工作?

问题描述 投票:0回答:1

我很难理解类方法对象在 Python 中的工作原理,尤其是在元类上下文中和

__new__
中。在我的特殊情况下,当我迭代赋予
members
__new__
时,我想获取类方法成员的名称。

对于普通方法,名称只是存储在

__name__
属性中,但对于类方法来说,显然没有这样的属性。我什至不知道如何调用类方法,因为也没有
__call__
属性。

有人可以向我解释类方法如何工作或向我指出一些文档吗?谷歌搜索没有找到任何结果。谢谢!

python metaclass class-method
1个回答
24
投票

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'

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

对于获取由

classmethod
包装的函数名称的特定任务:

In [29]: cm.__get__(None, dict).im_func.__name__
Out[29]: 'foo'
© www.soinside.com 2019 - 2024. All rights reserved.