子类里访问父类的同名属性,而又不想直接引用父类的名字,由于说不定何时会去修改它,因此数据仍是只保留一份的好。其实呢,还有更好的理由不去直接引用父类的名字,参见 Python’s super() considered super! | Deep Thoughts by Raymond Hettinger。html
这时候就该super()
登场啦——python
class A: def m(self): print('A') class B(A): def m(self): print('B') super().m() B().m()
固然 Python 2 里super()
是必定要参数的,因此得这么写:segmentfault
class B(A): def m(self): print('B') super(B, self).m()
须要提到本身的名字。这个名字也是动态查找的,在这种状况下替换第三方库中的类会出问题。ide
`super()`` 很好地解决了访问父类中的方法的问题。那么,若是要访问父类的父类(准确地说,是方法解析顺序(MRO)中位于第三的类)的属性呢?wordpress
好比,B 类是继承 A 的,它重写了 A 的 m 方法。如今咱们须要一个 C 类,它须要 B 类的一些方法,可是不要 B 的 m 方法,而改用 A 的。怎么间接地引用到 A 的 m 方法呢?使用self.__class__
确定是不行的,由于 C 还可能被进一步继承。spa
从文档中我注意到,super 的实现是经过插入一个名为 __class__
的名字来实现的(super 会从调用栈里去查找这个 __class__
名字)。因此,就像文档里暗示的,其实能够直接在定义方法时访问 __class__
名字,它老是该方法被定义的类。继续咱们的单字母类:code
class C(B): def m(self): print('C') # see the difference! print(__class__.__mro__) print(self.__class__.__mro__) __class__.__mro__[2].m(self) class D(C): def m(self): print('D') super().m() o = D() o.m()
会获得:htm
D C (<class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>) (<class 't.D'>, <class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>) A
不过,PyPy 并不支持这个 __class__
名字。继承