【问题标题】:What's the difference between a 'function', 'method' and 'bound method' in Python 3?Python 3 中的“函数”、“方法”和“绑定方法”有什么区别?
【发布时间】:2016-05-12 12:21:19
【问题描述】:

我观察到至少 3 种与 Python 3 中的函数相关的类型:

>>> class A():
...  def f(): pass
...
>>> A.f
<function A.f at 0x7fcaef304268>
>>> A().f
<bound method A.f of <__main__.A object at 0x7fcaef2fae80  
>>> set.union
<method 'union' of 'set' objects>

我想知道“函数”、“方法”和“绑定方法”有什么区别? 'method' 是 Python 2 中等价于 'unbound method' 的类型吗?

【问题讨论】:

    标签: python function python-3.x python-internals


    【解决方案1】:

    'method' 是 Python 2 中的 'unbound method' 等价的类型吗?

    种类-a-sort-a。但不是真的。它是用 C 代码定义的 method_descriptor 对象。它是一种未绑定的方法,但不是您在 Python 2 中找到的那种。

    对于编写为 C 的 Python 类型,所有“方法”实际上都是 C 函数。您找到的 &lt;method 'name' of 'type' objects&gt; 对象是一个特殊对象,您可以使用它来调用给定实例和更多参数的函数,就像 function 对象对自定义 Python 类所做的那样。该对象在 C 中的 PyMethodDescr_Type structure 中定义。它实现了descriptor protocol,就像函数一样。

    Python 定义了其他几种这样的描述符类型;如果使用__slots__,每个属性都是member_descriptor 类型的dsescriptor(参见PyMemberDescr_Type structure),而classmethodpropertystaticmethod 可能是更知名的描述符对象。

    在 Python 2 中,绑定和未绑定方法实际上只是 一个 类型,instancemethod(由 PyMethod_Type structure 定义);如果设置了__self__ (im_self) 属性,它将报告为已绑定。在 Python 3 中,使用函数作为描述符根本不会生成没有 __self__ 设置的方法对象;而是在没有实例的情况下调用 function.__get__() 再次返回该函数。

    Python 2 返回未绑定方法的唯一原因是强制类型检查;第一个参数必须是类(或其子类)的实例。这对于支持鸭子类型的 Python 代码没有多大意义,因此在 Python 3 中取消了该限制。但是,对于 C 代码,您不能使用鸭子类型,您仍然必须限制类型,这就是为什么 C-types 仍然返回一个强制此限制的 method_descriptor 对象。

    【讨论】:

      猜你喜欢
      • 2016-02-03
      • 1970-01-01
      • 2010-12-26
      • 2010-09-14
      • 1970-01-01
      • 2014-07-30
      • 2012-01-06
      • 2019-12-13
      相关资源
      最近更新 更多