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

Python超级方法和调用替代方法

江敏学
2023-03-14
问题内容

我到处都看到应通过以下方式调用超类方法的示例:

super(SuperClass, instance).method(args)

这样做有什么不利之处吗?

SuperClass.method(instance, args)

问题答案:

请考虑以下情况:

class A(object):
    def __init__(self):
        print('Running A.__init__')
        super(A,self).__init__()
class B(A):
    def __init__(self):
        print('Running B.__init__')        
        # super(B,self).__init__()
        A.__init__(self)

class C(A):
    def __init__(self):
        print('Running C.__init__')
        super(C,self).__init__()
class D(B,C):
    def __init__(self):
        print('Running D.__init__')
        super(D,self).__init__()

foo=D()

因此,这些类形成了一个所谓的继承钻石:

    A
   / \
  B   C
   \ /
    D

运行代码会产生

Running D.__init__
Running B.__init__
Running A.__init__

不好,因为跳过了Cs __init__。其原因是因为B__init__调用A__init__直接。

的目的super是解决继承钻石。如果您取消评论

# super(B,self).__init__()

和注释掉

A.__init__(self)

该代码产生了更令人满意的结果:

Running D.__init__
Running B.__init__
Running C.__init__
Running A.__init__

现在,所有__init__方法都被调用。请注意,在当时你定义B.__init__你可能会 认为
super(B,self).__init__()是与调用A.__init__(self),但是你错了。在上述情况下,super(B,self).__init__()实际上调用C.__init__(self)

圣烟,
B一无所知C,却super(B,self)知道调用C__init__?原因是因为self.__class__.mro()包含C。换句话说,self(或以上所述foo)了解C

所以要小心-两者不可互换。它们可以产生截然不同的结果。

使用super 有陷阱。继承图中的所有类之间需要相当大的协调。(例如,它们必须具有相同的呼叫签名__init__,因为任何特定的__init__人都不知道__init__
super接下来会呼叫另一个,或者使用**kwargs。)此外,您必须在super任何地方都保持一致。跳过一次(如上例所示),您将失去的全部目的super。请参阅链接以了解更多陷阱。

如果您完全控制类的层次结构,或者避免使用继承菱形,则不需要super



 类似资料:
  • 问题内容: 是否可以从子静态方法调用超静态方法? 我的意思是,到目前为止,到目前为止,我有以下内容: 并且它可以工作,但是我想以一种通用的方式来做,就像调用super.loadState()一样,这似乎不起作用… 问题答案: 在Java中,静态方法不能被覆盖。原因在这里 得到了很好的解释 因此,它不依赖于被引用的对象。但是,它取决于引用的类型。因此,据说静态方法隐藏了另一个静态方法而不覆盖它。 例

  • 问题内容: 这是我的代码- 我想在课堂上嘲笑。但是我找不到解决办法。仅禁止并返回默认值(在上述情况下为0)。事情就是这样,,只对静态方法的工作。 有没有办法在Powermock中做到这一点? 我正在使用Powermock 1.5和Mockito 1.9.5。 问题答案: 看来jMockit可以满足我的需求。也许我可以将这个问题发布到powermock邮件列表中。同时下面就足够了。包learning

  • 问题内容: 我目前有这样的代码: 但是,这可能会在将来导致难以发现的错误,因为读者可能不会注意到上面出现的错误。或者,贡献者可能会错误地添加,而忘记添加。 我如何避免这种陷阱? 问题答案: 这样,实际上是一个“全局”。可以从任何地方对其进行读写。 与字典的替代方法相比,我更喜欢这种方法,因为它可以自动完成变量名。

  • 我编写了下面的Scala代码来处理传入的字符串,格式化字符串,将其附加到中,并将带有转义unicode的格式化的返回给调用方进行其他处理。 Scala编译器在有调用的行中抱怨以下错误:

  • 问题内容: 我希望当子类覆盖父类中的方法时,在该子方法中调用。 有什么办法在编译时检查吗? 如果没有,发生这种情况时,我将如何抛出运行时异常? 问题答案: 无法直接要求这样做。但是,您可以执行以下操作: 这提供了一个内部接口点,子类可以使用该接口将自定义行为添加到public 方法,同时确保无论子类做什么都始终执行超类行为。

  • 问题内容: 我有很大一部分不是循环的代码,只是发生一次但要花费一些时间的命令列表。我需要它根据更改的布尔值在任何时候暂停或终止此操作。我可以使用其他线程来挂起,恢复和停止此代码,但是不赞成使用这些方法,因此我想避免使用它们。我可以检查每行代码之间的布尔值,但我希望有一个更优雅的解决方案。有什么好方法吗? 问题答案: 自然,使用来处理中断线程的正确方法(在这种情况下,是暂停或停止线程)。它的设计目的