在Python-2.x中super()是否损坏?

发布于 2021-01-29 19:06:48

从目前的情况来看,这个问题不适合我们的问答形式。我们希望答案能得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。

7年前关闭。

人们经常说在Python
2中super应该避免使用super它。我在Python 2中的使用中发现,除非我提供所有示例这样的参数,否则它永远不会达到我期望的方式:

super(ThisClass, self).some_func(*args, **kwargs)

在我看来,这违背了使用的目的super(),它既不简洁也不比更好TheBaseClass.some_func(self, *args, **kwargs)。在大多数情况下,方法解析顺序是一个遥远的童话。

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    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()坏了。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看