深入理解Python中的super()方法
本文深入解析Python中super()方法的运行机制,对比经典类与新式类的继承差异。重点阐述单继承场景下super()的调用逻辑,并详细剖析多继承中基于C3算法的方法解析顺序(MRO)。通过具体代码示例,说明self参数传递对结果的影响及子类方法重写时的正确用法,帮助开发者掌握Python面向对象编程的核心机制。
前言
Python中的类分为新式类和经典类,两者均支持多继承机制。在类继承体系中,若需调用父类方法而非完全覆盖,可使用super()函数来实现对父类功能的扩展或重写。
Python的类继承机制与C++存在相似之处。在定义类时,Python默认包含第一个参数self,其作用类似于C++中的this指针,用于指向当前对象实例。
以下是一个简单的Python类示例:
>>> class hello(object): ... def print_c(): ... print"hello world!" >>> hello().print_c() hello world!
在实际开发中,类的继承不可避免。子类继承父类的标准写法如下:
>>> class child(hello): ... def print_c(self): ... hello().print_c() ... >>> child().print_c() hello world!
Python还提供了super()机制,具体示例如下:
>>> class hello(object): ... def print_c(self): ... print"hello world!" ... >>> class child(hello): ... def print_c(self): ... super(child,self).print_c() ... >>> child().print_c() hello world!
注意事项
Python 2.2之前的版本处于经典类(classic class)时代。
经典类是一种未显式继承object的类,其实例类型均为type。若将经典类作为父类,子类调用父类构造函数时会抛出错误:'''TypeError: must be type, not classobj'''。
此时,方法解析顺序(MRO)采用深度优先搜索(DFS)策略,子节点遍历顺序为从左到右。因此,本文讨论基于新式类,其搜索算法采用C3算法。
class C(object): def minus(self,x): return x/2 class D(C): def minus(self,x): super(D, self).minus() print 'hello'
在上述代码中,C为父类,D为子类。我们在D类中重新定义了minus方法,即在C类原有功能基础上增加print 'hello'的功能。super()的作用是在子类中调用父类方法,这是单继承中调用super()的常见用法。接下来探讨更复杂的情况。
class A(object): def __init__(self): self.n = 10 def minus(self, m): self.n -= m class B(A): def __init__(self): self.n = 7 def minus(self, m): super(B,self).minus(m) self.n -= 2 b=B() b.minus(2) print b.n
在上述代码中,b.n的输出结果是多少?为何结果为2而非5?尽管super(B,self).minus(m)调用了父类的minus方法,但需注意此时操作的是B的实例而非A的实例。因此,传递的self.n数值为7,而非10。
那么,在多继承场景下,super()如何工作?现在创建一个继承自A的C类,再创建一个继承自B和C的D类,观察如何通过super()重写方法。
class C(A): def __init__(self): self.n = 12 def minus(self, m): super(C,self).minus(m) self.n -= 5 class D(B, C): def __init__(self): self.n = 15 def minus(self, m): super(D,self).minus(m) self.n -= 2 d=D() d.minus(2) print d.n
上述代码的输出结果是什么?别着急,先分析其运行过程。前文提及新式类查找子节点时使用C3算法。具体查找路径为:D->B->C->A->object。如何验证该顺序的正确性?
D.__mro__ (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
MRO(Method Resolution Order,方法解析顺序)是指Python为每个定义的类计算出的一个方法解析顺序列表,它代表了类继承的查找顺序。
总结
以上为本文全部内容,希望本文内容对您的学习或工作具有参考价值。如有疑问,欢迎留言交流,感谢支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









