python - 调用 super().method() 与 BaseClass.method(self)
问题描述
派生类调用基类的方法有两种主要方式。
Base.method(self):
class Derived(Base):
def method(self):
Base.method(self)
...
或super().method():
class Derived(Base):
def method(self):
super().method()
...
假设我现在这样做:
obj = Derived()
obj.method()
据我所知,两者都Base.method(self)
做super().method()
同样的事情。两者都会Base.method
调用obj
. 特别是,super()
不执行实例化类型对象的繁琐工作Base
。相反,它会创建一个类型的新对象super
并将实例属性移植到它上面,然后当您尝试从超级对象中获取它时obj
,它会动态查找正确的属性。Base
当您更改派生类的基类时,该super()
方法的优点是可以最大限度地减少您需要做的工作。另一方面,Base.method
当一个类从多个基类继承时,使用更少的魔法并且可能更简单和更清晰。
我看到的大多数讨论都建议调用super()
,但这是 Python 编码人员的既定标准吗?还是这两种方法都在实践中广泛使用?例如,这个 stackoverflow 问题的答案是双向的,但通常使用该super()
方法。另一方面,我这学期教的Python 教科书Base.method
只展示了这种方法。
解决方案
Usingsuper()
意味着下面的任何东西都应该委托给基类,不管它是什么。这是关于语句的语义。Base
另一方面,明确提及传达了Base
出于某种原因(读者可能不知道)明确选择的想法,这也可能有其应用。
然而除此之外还有一个非常实际的使用理由super()
,即协作多重继承。假设您设计了以下类层次结构:
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)
现在您可以同时使用Foo
和Bar
一切都按预期工作。然而,这两个类不能在多重继承模式中一起工作:
class Test(Foo, Bar):
pass
Test().test()
# Output:
# Foo.test
# Base.test
最后一次调用test
skip overBar
的实现,因为Foo
没有指定它要按方法解析顺序委托给下一个类,而是明确指定Base
。使用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
推荐阅读
- grails - 如何更改 grails 项目中的 URL?
- javascript - 试图避免在ajaxcall之后滚动条返回开始
- r - 优化例程在自动编码器包中的自动编码功能中给出错误
- c# - 将 Office 互操作图像附件转换为 OpenXML
- java - Apache CXF JAXB Marshaller 未正确编组 @XmlAttribute
- dialogflow-es - 如何从 WebHook 客户端检索登录认证结果?
- javascript - 在使用 webpack 转译 typescript 代码之前包含 XMLHttpRequest
- angular - Angular - 使用 Render2 在 Angular 组件中动态设置属性指令
- database - 阻止用户特权
- python - 为什么 Flask 不使用下面的代码呈现 html 页面?