python-3.x - 如何动态调用每个父级的__init__
问题描述
我已经阅读了关于 SO 与我的问题最相似的问题,这是关于单父继承的,唯一提到多父继承的答案建议读者使用调用该方法 ( )的静态形式,正如所指出的那样评论中的内容并不总是干净的。SomeSuperClass.someMethod(self, args)
我正在寻求一种动态someMethod
调用特定超类的特定方法的方法,例如:SomeSuperClass
class SomeSuperClass():
def someMethod(self, args):
print("Hello,", end="")
class Subclass(SomeSuperClass, OtherSuperClass):
def someMethod(self, args):
# static calling (I do not want this solution)
SomeSuperClass.someMethod(self, args)
# dynamic calling (I want this one)
(my SomeSuperClass-ness).someMethod(args)
print("world!")
这是我实际测试并希望工作的代码:
class Something():
def __init__(self, a, b) -> None:
self.sum = a+b
class SomethingElse():
def __init__(self, c, d) -> None:
self.product = c * d
class Both(Something, SomethingElse):
def __init__(self, a, b) -> None:
# sadly this does not work
super(Something, self).__init__(a, b)
super(SomethingElse, self).__init__(a, b)
# the following works, but is static and does not use super
# Something.__init__(self, a, b)
# SomethingElse.__init__(self, a, b)
b = Both(10, 20)
print(b.sum, b.product)
运行此代码会导致以下错误:
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
显然它正在尝试调用__init__
of object
。在这种情况下,如何super
正确使用它才能真正调用适当__init__
的 s?
解决方案
该函数将在您指定的之后super()
委托给父级 - 请参见此处,特别是以下注释:
对象或类型确定要搜索的方法解析顺序。搜索从紧随其后的类开始
type
。
所以要正确使用它,你应该使用super()
来指代Something
,和super(Something, self)
指代SomethingElse
; 您可以通过阅读类的__mro__
属性来查看顺序Both
:
class Something():
pass
class SomethingElse():
pass
class Both(Something, SomethingElse):
pass
print(Both.__mro__)
这会告诉你顺序:
(<class '__main__.Both'>, <class '__main__.Something'>, <class '__main__.SomethingElse'>, <class 'object'>)
并解释为什么你最后object.__init__
打电话给super(...).__init__(...)
.
推荐阅读
- clojure - LazySeq 不能在 sort-by 上强制转换为 Comparable
- c - 为什么没有 INT_BIT?
- java - Elasticsearch REST 客户端 MultiGet——GetResult 始终为空
- scala - Maven构建问题与命名空间冲突
- eclipse - Eclipse 中的 AWS SAM 本地运行时错误
- mailgun - 使用 ActionMailer 和 mailgun 标记消息
- javascript - 当我在 JavaScript 上单击下一个和上一个时,如何为数组设置顺序?
- python - 在 Python 中将 DataFrame 日期从英国更改为美国
- python - 使用 Jinja2 生成模板的所有变体
- excel - 根据日期范围从现有工作表中复制行