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

在派生类中调用super()时,可以传递self .__ class__吗?

章誉
2023-03-14
问题内容

我最近发现,在我应该调用的基类中调用方法:

super([[derived class]], self).[[base class method]]()

很好,可以。但是,我发现自己经常在类之间进行复制和粘贴,而常常忘记将派生类参数固定为super()函数。

我想避免必须记住要更改派生类参数。我是否可以仅将其self.__class__用作super()函数的第一个参数?

它似乎可行,但是有充分的理由为什么我不应该这样做?


问题答案:

你不能。该super()调用需要知道该方法属于哪个类,以在基类中搜索被覆盖的方法。

如果您在传递self.__class__(或更好,type(self))则super()给出 错误的 出发点,以寻找方法,并最终调用_再次它自己的方法_ 。

在构成方法解析顺序序列的类列表中,将其视为指针。如果传入,type(self)则指针将引用任何子类,而不是原始起点。

以下代码导致无限递归错误:

class Base(object):
    def method(self):
        print 'original'

class Derived(Base):
    def method(self):
        print 'derived'
        super(type(self), self).method()

class Subclass(Derived):
    def method(self):
        print 'subclass of derived'
        super(Subclass, self).method()

演示:

>>> Subclass().method()
subclass of derived
derived
derived
derived

<... *many* lines removed ...>

  File "<stdin>", line 4, in method
  File "<stdin>", line 4, in method
  File "<stdin>", line 4, in method
RuntimeError: maximum recursion depth exceeded while calling a Python object

因为type(self)Subclass没有 DerivedDerived.method()

在这个例子中,MRO为Subclass[Subclass, Derived, Base],而super()需要知道从哪里开始寻找任何替代的方法。通过使用type(self)它告诉它从开始Subclass,所以它将Derived.method()在我们开始的地方找到下一个。



 类似资料:
  • 我无法将派生类传递给接受基类作为参数的函数。基类由“障碍物”组成,这些障碍物将被放置在“板”上。无效的board::setvalue(int-length、int-width、board 但是,这会导致编译器给出“未知参数转换…”错误。在浏览站点时,我发现我应该将派生对象作为常量进行传递,但这会导致问题,因为无法将常量分配给线路板(因为它包含指向非常量障碍物的指针)。 反过来,将线路板更改为包含常

  • 我可以写: 但这当然不起作用,因为调用返回的是而不是我想要的。 我可以通过在(以及和等)中键入类型并抑制警告来避免这个问题,但是即使只有(比方说)10个扩展的实体类,这仍然是为了键入而编写的样板代码。此外,我认为,如果我必须为每个派生类编写代码(无论多么小)(也会有其他类似的方法),那么拥有类层次结构的好处就会丧失很多。 对此有更好的解决方案吗? 更新:使用Java7。

  • 问题内容: 有什么方法可以轻松解决此问题,或者我真的需要重写所有旧代码吗? PHP致命错误:第30行的…中的调用时传递引用已被删除 当变量在整个代码中作为引用传递给函数时,这种情况随处可见。 问题答案: 您应该在函数定义中通过引用表示调用,而不是实际调用。由于PHP在5.3版中开始显示弃用错误,因此我想重写代码是一个好主意。 从文档中: 函数调用上没有参考符号-仅在函数定义上。 仅函数定义就足以正

  • 问题内容: 我在基类中定义了一个静态方法,我想在其子类中重写此方法,这可能吗? 我尝试了一下,但是没有按预期工作。当我创建类B的实例并调用其callMe()方法时,将调用类A中的静态foo()方法。 问题答案: 静态方法调用在编译时解决(不动态分配)。 给

  • 在路径上使用 super (父级)和 self(自身)关键字,可以在访问项时消除歧义和防止不必要的路径的硬编码。 fn function() { println!("called `function()`"); } mod cool { pub fn function() { println!("called `cool::function()`"); }

  • 问题内容: 在子类中重写方法时,我经常这样做: 我的问题是:super(type(self),self)是否有捷径? 问题答案: 不要那样做:如果仅可以将其用作第一个参数,那么就不必将它放在第一位。您必须在此处传递实际的类,而不是如果该类已被子类化的表达式可能会更改的表达式。 super的第一个参数必须是包含当前方法定义的类,因为您要告诉super在基础列表中从哪里开始搜索。 Python 3知道