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 * valueclass 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 * valueclass 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.jclass 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 42b = BLogged(i=3, j=4)
将此与使用显式超类调用进行比较。您可以选择自己喜欢的版本。]
这和类似的故事就是为什么我认为
super()不应将其视为基类的标准调用方法的原因 。这并不意味着
super()坏了。



