简体   繁体   English

调用 super().method() 与 BaseClass.method(self)

[英]Calling super().method() vs. BaseClass.method(self)

There are two main ways for a derived class to call a base class's methods.派生的 class 有两种主要方式来调用基类的方法。

Base.method(self): Base.method(self):

class Derived(Base):
    def method(self):
        Base.method(self)
        ...

or super().method():super().method():

class Derived(Base):
    def method(self):
        super().method()
        ...

Suppose I now do this:假设我现在这样做:

obj = Derived()
obj.method()

As far as I know, both Base.method(self) and super().method() do the same thing.据我所知, Base.method(self)super().method()都做同样的事情。 Both will call Base.method with a reference to obj .两者都将调用Base.method并引用obj In particular, super() doesn't do the legwork to instantiate an object of type Base .特别是, super()不会做任何工作来实例化Base类型的 object 。 Instead, it creates a new object of type super and grafts the instance attributes from obj onto it, then it dynamically looks up the right attribute from Base when you try to get it from the super object.相反,它会创建一个super类型的新 object 并将实例属性从obj移植到它上面,然后当您尝试从 super object 获取它时,它会动态地从Base中查找正确的属性。

The super() method has the advantage of minimizing the work you need to do when you change the base for a derived class.当您更改派生 class 的基数时, super()方法的优点是可以最大限度地减少您需要做的工作。 On the other hand, Base.method uses less magic and may be simpler and clearer when a class inherits from multiple base classes.另一方面,当 class 从多个基类继承时, Base.method使用较少的魔法并且可能更简单、更清晰。

Most of the discussions I've seen recommend calling super() , but is this an established standard among Python coders?我见过的大多数讨论都建议调用super() ,但这是 Python 编码器中的既定标准吗? Or are both of these methods widely used in practice?还是这两种方法都在实践中广泛使用? For example, answers to this stackoverflow question go both ways, but generally use the super() method.例如, 这个 stackoverflow 问题go 两种方式的答案,但通常使用super()方法。 On the other hand, the Python textbook I am teaching from this semester only shows the Base.method approach.另一方面,我本学期教的Python 教科书只显示了Base.method方法。

Using super() implies the idea that whatever follows should be delegated to the base class, no matter what it is.使用super()意味着下面的任何内容都应该委托给基础 class,无论它是什么。 It's about the semantics of the statement.这是关于语句的语义。 Referring explicitly to Base on the other hand conveys the idea that Base was chosen explicitly for some reason (perhaps unknown to the reader), which might have its applications too.另一方面,明确引用Base传达了Base是出于某种原因(读者可能不知道)被明确选择的想法,这也可能有其应用。

Apart from that however there is a very practical reason for using super() , namely cooperative multiple inheritance .除此之外,使用super()有一个非常实际的原因,即协作多个 inheritance Suppose you've designed the following class hierarchy:假设您设计了以下 class 层次结构:

class Base:
    def test(self):
        print('Base.test')

class Foo(Base):
    def test(self):
        print('Foo.test')
        Base.test(self)

class Bar(Base):
    def test(self):
        print('Bar.test')
        Base.test(self)

Now you can use both Foo and Bar and everything works as expected.现在您可以同时使用FooBar并且一切都按预期工作。 However these two classes won't work together in a multiple inheritance schema:但是,这两个类不能在多个 inheritance 模式中一起工作:

class Test(Foo, Bar):
    pass

Test().test()
# Output:
# Foo.test
# Base.test

That last call to test skips over Bar 's implementation since Foo didn't specify that it wants to delegate to the next class in method resolution order but instead explicitly specified Base .最后一次调用test跳过了Bar的实现,因为Foo没有指定它想按方法解析顺序委托给下一个 class ,而是明确指定Base Using super() resolves this issue:使用super()解决了这个问题:

class Base:
    def test(self):
        print('Base.test')

class Foo(Base):
    def test(self):
        print('Foo.test')
        super().test()

class Bar(Base):
    def test(self):
        print('Bar.test')
        super().test()

class Test(Foo, Bar):
    pass

Test().test()
# Output:
# Foo.test
# Bar.test
# Base.test

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM