当前位置: 首页 > 面试题库 >

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

湛钊
2023-03-14
问题内容

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

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



 类似资料:
  • 问题内容: 我正在尝试做一个简单的例子… 在IE10中 窗口/标签页之间(相对于iframe) 跨起源 删除这些条件中的任何一个,一切正常:-) 但是据我所知,只有两个窗口共享一个原点时,窗口间才在IE10中起作用。(事实上​​,而且很奇怪,这种行为比这更宽松:共享 宿主的 两个不同来源似乎也起作用)。 (注意:此问题涉及问题,但答案是关于IE8和IE9的,而不是10) 更多详情+示例… 启动器页

  • 问题内容: 有些人认为这样做存在一些缺陷,即使正确使用也无法保护您的查询。 带一些化石的物品作为证明。 因此,问题是:mysql [i] _real escape_string()完全不可接受吗? 还是仍然可以使用此功能来创建自己的预备语句? 请提供校对码。 问题答案: 从MySQL的C API函数描述 : 如果需要更改连接的字符集,则应使用函数而不是执行(或)语句。的工作方式类似,但也会影响所使

  • 我们有大约200,00行的大型代码库,其中Spring2.X被用作基本的应用程序开发框架。我们正在考虑对Spring4.X进行一次重大(也是痛苦的)升级,原因很简单,Spring2.X似乎不再有任何商业支持。 我还注意到,Spring Framework的最新版本2.5.6在过去5年中没有任何错误或安全修复?这是否意味着Spring2.X是一个孤立的项目? http://sourceforge.n

  • 问题内容: 本来我想问这个问题,但是后来我发现它已经被想到了…… 在谷歌搜索中,我发现了扩展configparser的示例。以下适用于Python 3: 但不支持Python 2: 然后,我读了一些关于Python New Class vs. Old Class样式的信息(例如,在这里。现在我很想知道,我可以这样做: 但是,我不应该叫init吗?这在Python 2中是否等效: 问题答案: (不带

  • 问题内容: 我使用IPython笔记本,并希望能够选择在IPython中创建2.x或3.x python笔记本。 我最初有Anaconda。使用Anaconda时,必须更改全局环境变量以选择所需的python版本,然后才能启动IPython。这不是我想要的,所以我卸载了Anaconda,现在使用MacPorts和PiP设置了自己的安装。看来我还是要用 在python 2.x和3.x之间切换。这并不

  • 问题内容: 首先,一个简单的测试代码: 该测试代码使用Java 7仅创建一个文件“ test_0_0.log”,无论我运行该程序的频率如何。这是预期的行为,因为构造函数中的append参数设置为true。 但是,如果我使用Java 8运行此示例,则每次运行都会创建一个新文件(test_0_0.log,test_0_1.log,test_0_2.log等)。我认为这是一个错误。 恕我直言,Java的