从类中的一个方法继承的两个方法在实例中是不同的,不是吗?

时间:2018-02-11 21:29:20

标签: python python-3.x inheritance

有人可以解释为什么会这样吗?

class Foo:
    def bar(self):
        pass

a = Foo()
b = Foo()

a.bar == b.bar # False
a.bar is b.bar # False

我认为他们都继承了类方法,而且它是一种方法。

1 个答案:

答案 0 :(得分:5)

当您通过类上定义的实例访问函数时,每次都会创建一个 bound-method 对象。来自docs

  

调用方法时究竟发生了什么?你可能已经注意到了   x.f()在没有参数的情况下被调用,即使是   f()的函数定义指定了一个参数。发生了什么事   这个论点?当一个函数时,Python肯定会引发异常   需要一个没有任何参数的参数 - 即使是参数   实际上并未使用......

     

实际上,你可能已经猜到了答案:特别的事情   方法是将实例对象作为第一个参数传递   功能。在我们的示例中,调用x.f()完全等同于   MyClass.f(x)。通常,使用n个参数列表调用方法   相当于用参数调用相应的函数   通过之前插入方法的实例对象创建的列表   第一个论点。

     

如果你仍然不明白方法是如何工作的,那么看看   实施也许可以澄清问题。 当一个实例属性时   引用的不是数据属性,搜索其类。如果   name表示一个有效的class属性,它是一个函数对象,a   方法对象是通过打包(指向)实例对象来创建的   和一个在抽象对象中一起找到的函数对象:   这是方法对象。

注意,每次访问方法时都会发生

>>> class Foo:
...    def bar(self): pass
...
>>> f = Foo()
>>> f.bar is f.bar
False

这是如何工作的?实际上,functions are descriptor objects,请注意__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中实现!)。

另请注意,直接在课堂上访问该功能当然不会这样做(至少在你已经在你的问题上标记的Python 3上):

>>> Foo.bar is Foo.bar
True