用户定义的方法和__func__属性

时间:2014-09-12 10:30:28

标签: python python-2.7

有人可以解释Python datamodel reference中关于用户定义函数的以下部分是什么意思吗?

  

通过检索另一个方法对象来创建用户定义的方法对象   方法对象来自类或实例,行为与之相同   对于函数对象,除了新的__func__属性   instance不是原始方法对象,而是__func__属性。

我尝试用以下方法测试:

class A(object):
    def foo(self):
        print 'done'
    bar = foo
class B(object): pass

a = A()
b = B()
b.f = a.foo
b.f.__func__  #output:- <function foo at 0x7fe55bed4230>
a.foo.__func__ #output:- <function foo at 0x7fe55bed4230>

这两个陈述都给了我相同的输出但b.f.__func__没有给我原件 方法对象。我理解正确吗?

1 个答案:

答案 0 :(得分:2)

该文本描述了绑定行为;如果一个方法已被绑定,但你通过descriptor protocol检索它,那么方法对象就像一个函数对象,但__func__属性被重用,而不是让新的方法对象指向老。

通过访问foo作为类或实例的属性来触发描述符协议:

>>> class A(object):
...     def foo(self):
...         print 'done'
... 
>>> a = A()
>>> a.foo
<bound method A.foo of <__main__.A object at 0x1007611d0>>
>>> A.foo
<unbound method A.foo>
>>> A.__dict__['foo']
<function foo at 0x10075cc08>
>>> A.bar = A.foo
>>> A.bar
<unbound method A.foo>
>>> A.__dict__['bar']
<unbound method A.foo>
>>> a.bar
<bound method A.foo of <__main__.A object at 0x1007611d0>>
>>> a.bar.__func__
<function foo at 0x10075cc08>

在上面的会话中,我使用A.__dict__来绕过描述符协议。您可以看到A.__dict__['foo']是一个函数对象,但A.__dict__['bar']是一个未绑定的方法。但是,当您访问A.bara.bar时,您会获得一个指向原始函数对象的方法对象,而不是我们从A.foo检索到的方法。

所以你的理解似乎是正确的; b.f是(绑定)a.foo方法,因此b.f.__func__将导致与a.foo.__func__相同的对象。