方法对象VS函数对象,Python类实例VS类(method objects vs function

2019-07-18 04:19发布

我试图验证之间差异实例属性和经日期2012年11月1日,第9章Python的教程版本2.7.3布局类属性:类,第66页最后一行( 来源 ):

一个实例对象的有效方法名依赖于它的类。 按照定义,是函数对象类的所有属性定义其实例的相应的方法。 所以在我们的例子中,xf是一个有效的方法引用,因为MyClass.f是一个函数,但xi不是,因为MyClass.i是不是函数。 但XF是不一样的东西MyClass.f -它是一个方法对象,不是一个函数对象。

我有这个:

class MyClass:    
   """A simple example class"""    
   i = 12345   
   def f():    
      return 'hello world'

然后,我这样做:

>>> x = MyClass()
>>> x.f
<bound method MyClass.f of <__main__.MyClass instance at 0x02BB8968>>
>>> MyClass.f
<unbound method MyClass.f>
>>> type(MyClass.f)
<type 'instancemethod'>
>>> type(x.f)
<type 'instancemethod'>

需要注意的是这两种类型xfMyClass.f是instancemethod。 有一个在类型没有什么区别,但教程,否则说。 有人请澄清?

Answer 1:

绑定 VS 非绑定方法-一个解释。

...为什么Python有你指出的行为。

所以,第一关,记下这是3.x的不同 在3.x中,你会得到MyClass.f是一个功能, xf作为一种方法-如预期。 这种行为本质上是后来被改变了不良的设计决策。

这样做的原因是,Python有那就是大多数语言不同,它基本上是与第一个参数预先填充作为实例(的功能的方法的概念self )。 该预填充使得绑定的方法

>>> x.foo
<bound method MyClass.foo of <__main__.MyClass instance at 0x1004989e0>>

在Python 2.x和之前,将其理由是,没有连接到一个实例的方法将是一个未结合的方法 ,该方法是与第一参数(限制函数self ),必须是对象的一个实例。 这是随时可以被绑定到一个实例,并成为一个绑定方法

>>> MyClass.foo
<unbound method MyClass.foo>

随着时间的推移,人们清楚的不受约束的方法仅仅是一个与这个奇怪的限制,即没有多大关系(即函数self必须是“正确”的类型),所以他们从语言(在3.X)去除。 这实质上是鸭打字self ,它适合的语言。

Python 3.3.0 (default, Dec  4 2012, 00:30:24) 
>>> x.foo
<bound method MyClass.foo of <__main__.MyClass object at 0x100858ed0>>
>>> MyClass.foo
<function MyClass.foo at 0x10084f9e0>

进一步阅读。

这是一个(凝聚,从内存中)的说明,可以全部从Python的创造者吉多·范罗苏姆自己的嘴在读他的一系列“Python的历史” 。



Answer 2:

本教程确实是错误的; 既class.functionnameinstance.functionname返回一个方法的对象。

发生的事情是,一个函数是一个描述符和他们__get__方法被调用,返回的方法。 方法有__func__指向回到原来的功能属性:

>>> class Foo(object):
...     def bar(self):
...         pass
... 
>>> Foo.bar
<unbound method Foo.bar>
>>> Foo().bar
<bound method Foo.bar of <__main__.Foo object at 0x1090d6f10>>
>>> # accessing the original function
...
>>> Foo.bar.__func__
<function bar at 0x1090cc488>
>>> # turning a function back into a method
...
>>> Foo.bar.__func__.__get__(None, Foo)
<unbound method Foo.bar>
>>> Foo.bar.__func__.__get__(Foo(), Foo)
<bound method Foo.bar of <__main__.Foo object at 0x1090d6f90>>

这一切都在Python 3虽然改变; 有Foo.bar返回本身的功能,非绑定方法不再存在:

$ python3.3
Python 3.3.0 (default, Sep 29 2012, 08:16:08) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo:
...     def bar(self):
...         pass
... 
>>> Foo.bar
<function Foo.bar at 0x105512dd0>
>>> Foo.bar.__get__(None, Foo)
<function Foo.bar at 0x105512dd0>
>>> Foo.bar.__get__(Foo(), Foo)
<bound method Foo.bar of <__main__.Foo object at 0x10552fe10>>


文章来源: method objects vs function objects , Python class instances vs class