[英]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.现在您可以同时使用
Foo
和Bar
并且一切都按预期工作。 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.