在Python-2.x中super()是否损坏?
从目前的情况来看,这个问题不适合我们的问答形式。我们希望答案能得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。
7年前关闭。
人们经常说在Python
2中super
应该避免使用super
它。我在Python 2中的使用中发现,除非我提供所有示例这样的参数,否则它永远不会达到我期望的方式:
super(ThisClass, self).some_func(*args, **kwargs)
在我看来,这违背了使用的目的super()
,它既不简洁也不比更好TheBaseClass.some_func(self, *args,
**kwargs)
。在大多数情况下,方法解析顺序是一个遥远的童话。
- 除了2.7是Python 2的最后一个主要版本这一事实之外,为什么super在Python 2中仍然被破坏?
- Python 3的超级版本如何以及为何发生了变化?有什么警告吗?
- 我
super
什么时候以及为什么要使用向前?
-
super()
不会损坏-不应将其视为调用基类方法的标准方法。使用Python 3.x并没有改变。唯一更改的是,您不需要self, cls
在标准情况下传递参数,该情况self
是当前函数的第一个参数,并且cls
是当前正在定义的类。关于您何时使用的问题
super()
,我的回答是:几乎不会。我个人试图避免那种super()
有用的多重继承。编辑 :我曾经遇到过的现实生活中的一个例子:我有一些类定义了一个
run()
方法,其中一些具有基类。我曾经super()
称呼继承的构造函数-
我认为这并不重要,因为我仅使用单一继承:class A(object): def __init__(self, i): self.i = i def run(self, value): return self.i * value class B(A): def __init__(self, i, j): super(B, self).__init__(i) self.j = j def run(self, value): return super(B, self).run(value) + self.j
试想一下,其中有几个类,都具有单独的构造函数原型,并且都具有与相同的接口
run()
。现在,我想为所有这些类添加一些其他功能,例如日志记录。附加功能要求在所有这些类上都定义一个附加方法,例如
info()
。我不想入侵原始类,而是定义从原始类继承的第二组类,添加info()
方法并从提供实际日志记录的混入中继承。现在,我不能再super()
在构造函数中使用了,所以我使用了直接调用:class Logger(object): def __init__(self, name): self.name = name def run_logged(self, value): print "Running", self.name, "with info", self.info() return self.run(value) class BLogged(B, Logger): def __init__(self, i, j): B.__init__(self, i, j) Logger.__init__("B") def info(self): return 42
在这里事情停止了。该
super()
基类的构造函数调用突然来电Logger.__init__()
,并且BLogged
不能做任何事情。除了删除super()
呼叫B
本身以外,实际上没有任何方法可以使这项工作有效。[ 另一个编辑 :从这里和其他答案下面的所有评论来看,我似乎没有表达我的观点。这是使用以下代码使代码工作的方法
super()
:class A(object): def __init__(self, i, **kwargs): super(A, self).__init__(**kwargs) self.i = i def run(self, value): return self.i * value class B(A): def __init__(self, j, **kwargs): super(B, self).__init__(**kwargs) self.j = j def run(self, value): return super(B, self).run(value) + self.j class Logger(object): def __init__(self, name, **kwargs): super(Logger,self).__init__(**kwargs) self.name = name def run_logged(self, value): print "Running", self.name, "with info", self.info() return self.run(value) class BLogged(B, Logger): def __init__(self, **kwargs): super(BLogged, self).__init__(name="B", **kwargs) def info(self): return 42 b = BLogged(i=3, j=4)
将此与使用显式超类调用进行比较。您可以选择自己喜欢的版本。]
这和类似的故事就是为什么我认为
super()
不应将其视为基类的标准调用方法的原因 。这并不意味着super()
坏了。