Python 超级方法和调用替代方法
我到处都看到应该通过以下方式调用超类方法的示例:
super(SuperClass, instance).method(args)
这样做有什么缺点吗:
SuperClass.method(instance, args)
I see everywhere examples that super-class methods should be called by:
super(SuperClass, instance).method(args)
Is there any disadvantage to doing:
SuperClass.method(instance, args)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
考虑以下情况:
因此,这些类形成了所谓的继承菱形:
运行代码会产生结果
这很糟糕,因为跳过了
C
的__init__
。原因是B
的__init__
直接调用A
的__init__
。super的目的是解决继承钻石。如果您取消注释
并注释掉
代码,则会产生更理想的结果:
现在所有
__init__
方法都会被调用。请注意,在定义 B.__init__ 时,您可能会认为 super(B,self).__init__() 与调用相同A.__init__(self)
,但你错了。在上述情况下,super(B,self).__init__()
实际上调用了C.__init__(self)
。天哪,
B
对C
一无所知,但super(B,self)
知道调用C
' s__init__
?原因是因为self.__class__.mro()
包含C
。换句话说,self
(或者上面的foo
)了解C
。所以要小心——两者是不可替代的。它们可以产生截然不同的结果。
使用
super
有陷阱。 所有的组件之间需要相当程度的协调。继承图中的类。 (例如,它们必须具有相同的__init__
调用签名,因为任何特定的__init__
都不知道还有哪个__init__
super
可能会调用 next,或者否则使用
**kwargs
.) 此外,您必须在任何地方都使用super
保持一致。跳过一次(如上面的示例),您就违背了super
的全部目的。请参阅链接了解更多陷阱。
如果您可以完全控制类层次结构,或者避免继承菱形,那么就不需要
super
。Consider the following situation:
So the classes form a so-called inheritance diamond:
Running the code yields
That's bad because
C
's__init__
is skipped. The reason for that is becauseB
's__init__
callsA
's__init__
directly.The purpose of
super
is to resolve inheritance diamonds. If you un-commentand comment-out
the code yields the more desireable result:
Now all the
__init__
methods get called. Notice that at the time you defineB.__init__
you might think thatsuper(B,self).__init__()
is the same as callingA.__init__(self)
, but you'd be wrong. In the above situation,super(B,self).__init__()
actually callsC.__init__(self)
.Holy smokes,
B
knows nothing aboutC
, and yetsuper(B,self)
knows to callC
's__init__
? The reason is becauseself.__class__.mro()
containsC
. In other words,self
(or in the above,foo
) knows aboutC
.So be careful -- the two are not fungible. They can yield vastly different results.
Using
super
has pitfalls. It takes a considerable level of coordination between all the classes in the inheritance diagram. (They must, for example, either have the same call signature for__init__
, since any particular__init__
would not know which other__init__
super
might call next, orelse use
**kwargs
.) Furthermore, you must be consistent about usingsuper
everywhere. Skip it once (as in the above example) and you defeat the entire purpose ofsuper
.See the link for more pitfalls.
If you have full control over your class hierarchy, or you avoid inheritance diamonds, then there is no need for
super
.尽管你的例子有些误导,但没有任何惩罚。在第一个示例中,它应该是
,这导致我引用 Python 文档 :
基本上,通过使用第一种方法,您不必在单类层次结构中对父类进行硬编码,并且在使用多个方法时,您根本无法真正使用第二种方法(有效地/有效地)执行您想要的操作遗产。
There's no penalty as-is, though your example is somewhat misguided. In the first example, it should be
and that leads me to quote the Python docs:
Basically, by using the first method you don't have to hard-code your parent class in there for single-class hierarchies, and you simply can't really do what you want (efficiently/effectively) using the second method when using multiple inheritance.