类方法对象如何工作? [英] How does a classmethod object work?

查看:74
本文介绍了类方法对象如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解类方法对象在Python中是如何工作的,尤其是在元类和__new__中.在我的特殊情况下,当我遍历赋予__new__members时,我想获得一个classmethod成员的名称.

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

有人可以向我解释类方法的工作原理或为我提供一些文档吗?谷歌搜索使我无处可去.谢谢!

解决方案

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

简而言之,描述符是具有方法__get__的对象,该方法带有三个参数:selfinstanceinstance 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相对应的参数(如果有的话),并且仅当在包装函数上调用__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'

I'm having trouble to understand how a classmethod object works in Python, especially in the context of metaclasses and in __new__. In my special case I would like to get the name of a classmethod member, when I iterate through the members that were given to __new__.

For normal methods the name is simply stored in a __name__ attribute, but for a classmethod there is apparently no such attribute. I don't even see how the classmethod is invoked, as there is no __call__ attribute either.

Can someone explain to me how a classmethod works or point me to some documentation? Googling led me nowhere. Thanks!

解决方案

A classmethod object is a descriptor. You need to understand how descriptors work.

In a nutshell, a descriptor is an object which has a method __get__, which takes three arguments: self, an instance, and an instance type.

During normal attribute lookup, if a looked-up object A has a method __get__, that method gets called and what it returns is substituted in place for the object A. This is how functions (which are also descriptors) become bound methods when you call a method on an object.

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 object works the same way. When it gets looked up, its __get__ method gets called. The __get__ of a classmethod discards the argument corresponding to the instance (if there was one) and only passes along the instance_type when it calls __get__ on the wrapped function.

A illustrative 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'>

More info on descriptors can be found here (among other places): http://users.rcn.com/python/download/Descriptor.htm

For the specific task of getting the name of the function wrapped by a classmethod:

In [29]: cm.__get__(None, dict).im_func.__name__
Out[29]: 'foo'

这篇关于类方法对象如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆