如何动态调用每个父级的__init__
How to call the __init__ of each parent dynamically
我读过 the most similar question on SO to my question, which was about single-parent inheritance and the only answer that mentioned multi-parent inheritance advised the reader to use the static form of calling that method (SomeSuperClass.someMethod(self, args)
), which, as pointed out in the comments 并不总是干净的。
我正在寻求一种方法来调用特定超类 SomeSuperClass
的特定方法 someMethod
动态 ,因此:
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)
显然它正在尝试调用 object
的 __init__
。在这种情况下,如何正确使用 super
才能真正调用适当的 __init__
s?
super()
函数将在您指定的 之后将 委托给父级 - 请参阅 here,具体说明如下:
The object-or-type determines the method resolution order to be searched. The search starts from the class right after the type
.
所以要正确使用,应该用super()
来指代Something
,用super(Something, self)
来指代SomethingElse
;您可以通过阅读 Both
class:
的 __mro__
属性 查看顺序
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'>)
并解释为什么您在第二次调用 super(...).__init__(...)
时最终调用 object.__init__
。
我读过 the most similar question on SO to my question, which was about single-parent inheritance and the only answer that mentioned multi-parent inheritance advised the reader to use the static form of calling that method (SomeSuperClass.someMethod(self, args)
), which, as pointed out in the comments 并不总是干净的。
我正在寻求一种方法来调用特定超类 SomeSuperClass
的特定方法 someMethod
动态 ,因此:
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)
显然它正在尝试调用 object
的 __init__
。在这种情况下,如何正确使用 super
才能真正调用适当的 __init__
s?
super()
函数将在您指定的 之后将 委托给父级 - 请参阅 here,具体说明如下:
The object-or-type determines the method resolution order to be searched. The search starts from the class right after the
type
.
所以要正确使用,应该用super()
来指代Something
,用super(Something, self)
来指代SomethingElse
;您可以通过阅读 Both
class:
__mro__
属性 查看顺序
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'>)
并解释为什么您在第二次调用 super(...).__init__(...)
时最终调用 object.__init__
。