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

发布于 2021-01-29 19:35:55

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

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

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

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

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

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

    你不能。该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()在我们开始的地方找到下一个。



知识点
面圈网VIP题库

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

去下载看看