Ank*_*wal 20 python methods class instance
我正在尝试验证实例属性和类属性之间的区别,如2012年11月1日的Python教程版本2.7.3,第9章:类,最后一行(源代码)所示:
实例对象的有效方法名称取决于其类.根据定义,作为函数对象的类的所有属性都定义其实例的相应方法.所以在我们的例子中,xf是一个有效的方法引用,因为MyClass.f是一个函数,但是xi不是,因为MyClass.i不是.但是xf与MyClass.f不同 - 它是一个方法对象,而不是一个函数对象.
我有这个:
class MyClass:
"""A simple example class"""
i = 12345
def f():
return 'hello world'
Run Code Online (Sandbox Code Playgroud)
然后我这样做:
>>> 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'>
Run Code Online (Sandbox Code Playgroud)
需要注意的是这两种类型x.f
并MyClass.f
为instancemethod.类型没有区别,但教程另有说法.有人可以澄清一下吗?
Gar*_*tty 24
所以,首先,请注意这在3.x中是不同的.在3.x中,您将MyClass.f
成为一个函数,并x.f
作为一种方法 - 正如预期的那样.这种行为本质上是一个糟糕的设计决策,后来被改变了.
这样做的原因是Python有一个与大多数语言不同的方法的概念,它本质上是一个函数,第一个参数预先填充为instance(self
).这种预填充是一种约束方法.
>>> x.foo
<bound method MyClass.foo of <__main__.MyClass instance at 0x1004989e0>>
Run Code Online (Sandbox Code Playgroud)
在Python 2.x及之前,有人认为未附加到实例的方法是未绑定的方法,这是一个限制第一个参数(self
)必须是对象实例的函数.然后准备将其绑定到实例并成为绑定方法.
>>> MyClass.foo
<unbound method MyClass.foo>
Run Code Online (Sandbox Code Playgroud)
随着时间的推移,很明显一个未绑定的方法实际上只是一个具有这个奇怪限制的函数,它并不重要(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>
Run Code Online (Sandbox Code Playgroud)
这是一个(浓缩的,从内存中)解释,可以从他的"Python的历史"系列中的 Python创建者Guido van Rossum自己的口中全面阅读.
Mar*_*ers 13
该教程确实是错误的; 两者class.functionname
并instance.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>>
Run Code Online (Sandbox Code Playgroud)
这在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>>
Run Code Online (Sandbox Code Playgroud)