Home > Backend Development > Python Tutorial > Python中既然可以直接通过父类名调用父类方法为什么还会存在super函数?

Python中既然可以直接通过父类名调用父类方法为什么还会存在super函数?

WBOY
Release: 2016-06-06 16:22:26
Original
1419 people have browsed it

比如

<span class="k">class</span> <span class="nc">Child</span><span class="p">(</span><span class="n">Parent</span><span class="p">):</span>  
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>  
         <span class="n">Parent</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> 
Copy after login

回复内容:

针对你的问题,答案是可以,并没有区别。但是这题下的回答我感觉都不够好。

要谈论 super,首先我们应该无视 "super" 这个名字带给我们的干扰。

不要一说到 super 就想到父类!super 指的是 MRO 中的下一个类!
不要一说到 super 就想到父类!super 指的是 MRO 中的下一个类!
不要一说到 super 就想到父类!super 指的是 MRO 中的下一个类!

一说到 super 就想到父类这是初学者很容易犯的一个错误,也是我当年犯的错误。
忘记了这件事之后,再去看这篇文章:Python’s super() considered super!
这是 Raymond Hettinger 写的一篇文章,也是全世界公认的对 super 讲解最透彻的一篇文章,凡是讨论 super 都一定会提到它(当然还有一篇 Python's Super Considered Harmful)。

如果不想看长篇大论就去看这个答案,super 其实干的是这件事:
<code class="language-python"><span class="k">def</span> <span class="nf">super</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">inst</span><span class="p">):</span>
    <span class="n">mro</span> <span class="o">=</span> <span class="n">inst</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">mro</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">mro</span><span class="p">[</span><span class="n">mro</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">cls</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
</code>
Copy after login
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

总之前人留下的经验就是:保持一致性。要不全部用类名调用父类,要不就全部用 super,不要一半一半。

如果没有复杂的继承结构,super 作用不大。而复杂的继承结构本身就是不良设计。对于多重继承的用法,现在比较推崇 Mixin 的方式,也就是
  • 普通类多重继承只能有一个普通父类和若干个 Mixin 类(保持主干单一)
  • Mixin 类不能继承普通类(避免钻石继承)
  • Mixin 类应该单一职责(参考 Java 的 interface 设计,Mixin 和此极其相似,只不过附带实现而已)
如果按照上述标准,只使用 Mixin 形式的多继承,那么不会有钻石继承带来的重复方法调用,也不会有复杂的查找顺序 —— 此时 super 是可以有无的了,用不用全看个人喜好,只是记得千万别和类名调用的方式混用就好。 某个时候你觉得Parent名字不好了,改成MyParent,结果不得不把每个子类都改一遍

另外给一个类获得父类只能用super,比如:
def get_super(cls): super(A,self).func 不是把A的父类的func执行,而是把A的父类的类类型序列中的所有类型的func都执行一次。 blog.csdn.net/johnsongu
这里面写的挺好的,可以参考下 @laike9m 的解释很到位了,我想说:貌似没法解决参数传递问题啊,只能用python所谓的魔法,把参数全部传递过去,可是两个类,作者不同,什么事情都能发生,参数名重复呢,感觉python这个机制不怎么样 正好第一次接触到这问题,搬运工

inheritance - Understanding Python super() with __init__() methods
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template