在派生类中调用 super() 时,可以传入 self.__class__ 吗? [英] When calling super() in a derived class, can I pass in self.__class__?

查看:55
本文介绍了在派生类中调用 super() 时,可以传入 self.__class__ 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现(通过 StackOverflow)我应该调用基类中的方法:

super([[派生类]], self).[[基类方法]]()

没关系,它有效.但是,我发现自己在进行更改时经常在类之间复制和粘贴,并且经常忘记将派生类参数固定到 super() 函数.

我想避免必须记住更改派生类参数.我可以改为使用 self.__class__ 作为 super() 函数的第一个参数吗?

它似乎有效,但我不应该这样做有什么好的理由吗?

解决方案

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

如果你传入 self.__class__(或者更好的是,type(self))然后 super() 被赋予 错误的搜索方法的起点,最终会再次调用自己的方法.

将其视为构成方法解析顺序序列的类列表中的指针.如果你传入 type(self) 那么指针将指向任何子类而不是原始起点.

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

class Base(object):定义方法(自我):打印原始"派生类(基类):定义方法(自我):打印派生"超级(类型(自我),自我).方法()类子类(派生):定义方法(自我):打印派生的子类"超级(子类,自我).方法()

演示:

<预><代码>>>>子类().方法()派生的子类衍生的衍生的衍生的<... *许多*行已删除...>文件<stdin>",第 4 行,在方法中文件<stdin>",第 4 行,在方法中文件<stdin>",第 4 行,在方法中运行时错误:调用 Python 对象时超出了最大递归深度

因为type(self)Subclass不是 Derived,在Derived.method().

在示例中,Subclass 的 MRO 为 [Subclass, Derived, Base]super() 需要知道在哪里开始搜索任何被覆盖的方法.通过使用 type(self) 你告诉它从 Subclass 开始,所以它接下来会找到 Derived.method() ,这就是我们开始了.

I've recently discovered (via StackOverflow) that to call a method in a base class I should call:

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

That's fine, it works. However, I find myself often copying and pasting between classes when I make a change and frequently I forget to fix the derived class argument to the super() function.

I'd like to avoid having to remember to change the derived class argument. Can I instead just use self.__class__ as the first argument of the super() function?

It seems to work but are there good reasons why I shouldn't do this?

解决方案

No you cannot. The super() call needs to know what class the method is part of, to search the base classes for an overridden method.

If you pass in self.__class__ (or better still, type(self)) then super() is given the wrong starting point to search for methods, and will end up calling its own method again.

See it as a pointer in the list of classes that form the Method Resolution Order sequence. If you pass in type(self) then the pointer will refer to any subclasses instead of the original starting point.

The following code leads to an infinite recursion error:

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()

Demo:

>>> 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

because type(self) is Subclass, not Derived, in Derived.method().

In the example, the MRO for Subclass is [Subclass, Derived, Base], and super() needs to know where to start searching for any overridden methods. By using type(self) you tell it to start at Subclass, so it'll find Derived.method() next, which is where we started.

这篇关于在派生类中调用 super() 时,可以传入 self.__class__ 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆