请有人解释为什么这样?
class Foo:
def bar(self):
pass
a = Foo()
b = Foo()
a.bar == b.bar # False
a.bar is b.bar # False
我认为它们都继承了类方法,这是一种方法。
通过定义的实例访问函数时,每次都会创建一个绑定方法对象 is 。从文档:
当一个方法被调用时发生了什么?你可能已经注意到,在没有上面的参数的情况下调用 x.f()
,尽管 f()
的函数定义指定了参数。参数发生了什么变化?当需要参数的函数没有任何—时,即使参数不实际使用,python 也会引发异常。
实际上,你可能已经猜到了答案:关于方法的特殊内容是,实例对象作为函数的第一个参数传递。在我们的示例中,调用 x.f()
与 MyClass.f(x)
完全相同。通常,使用n 参数列表调用方法等同于在第一个参数之前插入方法对象的参数列表。
如果你还是不理解方法的工作原理,了解一下它的实现也许有帮助。当引用实例属性的引用不是数据属性时,它的类将被搜索。如果名称表示作为函数对象的有效类属性,则方法对象由包装( 指向) 和抽象对象中的函数对象创建。这是方法对象。
注意:每次访问方法时,都会发生这种情况:
>>> class Foo:
... def bar(self): pass
...
>>> f = Foo()
>>> f.bar is f.bar
False
这个函数是什么实际上,函数是描述descriptor的描述符对象,说明存在一个 __get__
:?
>>> def func(): pass
...
>>> func.__get__
<method-wrapper '__get__' of function object at 0x101e38ae8>
换句话说,你可以将 python 函数看作是实现:
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return types.MethodType(self, obj)
当然,它们在 python ( 至少在 CPython ) 中没有实现。
当然,直接在类上访问函数,并不这样做:
>>> Foo.bar is Foo.bar
True