在Python中使用super()是一个好主意吗?

14

还是直接引用想要调用方法的超类好呢?

在引用构造函数时重复超类名称似乎很脆弱,但是这个页面http://fuhm.net/super-harmful/提出了一些反对使用super()的有力观点。

6个回答

12

这本书《Expert Python Programming》在第3章中讨论了“super pitfalls”的主题,非常值得一读。以下是该书的结论:

使用 super 必须要一致:在类层次结构中,应该无处不用或者全都不用 super。混合使用 super 和经典调用是一种令人困惑的做法。人们往往避免使用 super,以使他们的代码更明确。

编辑:今天我再次阅读了这部分内容。我将复制一些更多的句子,因为使用 super 是棘手的:

  • 避免在代码中使用多重继承。
  • 在使用上要保持一致,不要混合新式和旧式方法。
  • 在调用子类的方法之前,请先检查类层次结构。

6

你可以使用super,但正如文章所述,它也有缺点。只要你知道这些缺点,使用这个特性就没有问题了。这就像人们说“使用组合而不是继承”或“永远不要使用全局变量”。如果这个特性存在,那么肯定有它的原因。只需要确保理解为什么和什么,明智地使用它们。


17
“如果某个功能存在,就会有它的存在原因。”这个论点是不正确的。很多语言存在一些特性,但它们不应该被任何人使用。 - Mike Graham
1
@MikeGraham,...嗯,这就是切斯特顿的栅栏。总会有一个原因,但这并不意味着多年后这个原因仍然相关。了解一个功能背后的历史是相关的,然而,这有助于理解是否还存在任何相关性。 - Charles Duffy

4

super() 试图为你解决多继承的问题;它的语义很难复制,除非你完全确定,否则不应创建任何新的语义。

对于单继承,super() 函数实际上没有什么区别。

class X(Y):
    def func(self):
        Y.func(self)

并且

class X(Y):
    def func(self):
        super().func()

所以我想这只是品味问题。

3

我更喜欢使用super(),因为它允许您在不更改所有方法的情况下更改继承类(例如,在重构并添加中间类时)。


2
除非你还没开始使用Python 3(大部分人都在使用),否则请返回仅翻译后的文本。 - nosklo
1
你是什么意思?super() 在 Python 2 中也存在。 - juanjux
我相信它已经被回溯了。 - ilya n.

1
人们对super的问题更多是关于多重继承的问题。因此,责怪super有点不公平。没有super,多重继承会变得更糟。Michele Simionato在他的博客文章中很好地总结了这个问题:

另一方面,人们可能会想知道所有的超级缺陷是否都暗示着一些严重的潜在问题。也许问题不在于super,也不在于协作方法:问题可能在于多重继承本身。

因此,主要的教训是应该尽量避免多重继承。
出于一致性考虑,我总是使用super,即使对于单重继承来说,它并不真正重要(除了不必知道父类名称的小优势)。在Python 3+中,super更加方便,所以那里应该一定要使用super。

0

是的,你应该使用super()而不是其他方法。这是Python 3中标准的对象继承模型。

只需在__init__方法中使用关键字参数,你就不会遇到太多问题。此外,你可以使用**kwargs来支持继承链中未定义的附加参数。

我同意它很脆弱,但使用继承类的名称也不会更好。


你写了一个好观点。但是你能否考虑让你的回答更加详细一些呢?是回答哪个问题的“是”呢?是问题标题“在Python中使用super()是一个好主意吗?”还是问题的第一行“或者我应该明确地引用我想要调用的超类的方法?”。在多次阅读你的回答后,我认为你建议明确引用超类而不是使用super。但是,在我看来,如果没有多次阅读,很难理解你的回答。 - Md. Abu Nafee Ibna Zahid
1
@Md.AbuNafeeIbnaZahid 添加了一些额外的措辞。希望这有所帮助。 - cmcginty
谢谢。现在好多了。 - Md. Abu Nafee Ibna Zahid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接