python - 方法对象 vs 函数对象,Python 类实例 vs 类

标签 python class methods instance

我正在尝试验证 2012 年 11 月 1 日 Python 教程 2.7.3 版第 9 章:类,第 66 页最后一行 (source) 中列出的实例属性和类属性之间的区别:

Valid method names of an instance object depend on its class. By definition, all attributes of a class that are function objects define corresponding methods of its instances. So in our example, x.f is a valid method reference, since MyClass.f is a function, but x.i is not, since MyClass.i is not. But x.f is not the same thing as MyClass.f — it is a method object, not a function object.

我有这个:

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

注意x.fMyClass.f 的类型都是instancemethod。类型没有区别,但教程另有说明。有人可以澄清一下吗?

最佳答案

Bound vs Unbound 方法 - 一个解释。

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

首先,请注意这在 3.x 中有所不同。在 3.x 中,您将得到 MyClass.f 作为函数,而 x.f 作为方法 - 正如预期的那样。这种行为本质上是一个糟糕的设计决策,后来被改变了。

这样做的原因是 Python 有一个不同于大多数语言的方法的概念,它本质上是一个函数,其中第一个参数预填充为实例 (self)。这种预填充会生成一个绑定(bind)方法

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

在 Python 2.x 和之前的版本中,没有附加到实例的方法被认为是 unbound 方法,这是一个具有第一个参数( self),必须是对象的一个​​实例。然后就可以将其绑定(bind)到一个实例并成为一个绑定(bind)方法

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

随着时间的推移,很明显,未绑定(bind)的方法实际上只是一个具有这种奇怪限制的函数,这并不重要(self 必须是 '正确' type),因此它们已从语言中删除(在 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 创建者 Guido van Rossum 自己的口中完整阅读 his 'History of Python' series .

关于python - 方法对象 vs 函数对象,Python 类实例 vs 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14298844/

相关文章:

css - 使用正则表达式查找不在注释中的 CSS 类名

java - Android 代码中扭曲的 Java 方法需要足够的关注

java - 什么时候 Java 子例程不是方法?

javascript - 如何将Python创建的JSON数据发送到JavaScript?

python - 从数据库中获取后,在表单中设置选择项

c++ - 类函数/变量是否必须在使用前声明?

c++ - VSC throw 预期为 ')'

python - python 2.x中不可避免的 'encoding is an invalid keyword'错误吗?

Python tkinter 菜单+变量

python - 在另一个方法中运行一个方法。 Python