python多重继承使用super将参数传递给构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34884567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
python multiple inheritance passing arguments to constructors using super
提问by Lin
Consider the following snippet of python code
考虑以下python代码片段
class A(object):
def __init__(self, a):
self.a = a
class B(A):
def __init__(self, a, b):
super(B, self).__init__(a)
self.b = b
class C(A):
def __init__(self, a, c):
super(C, self).__init__(a)
self.c = c
class D(B, C):
def __init__(self, a, b, c, d):
#super(D,self).__init__(a, b, c) ???
self.d = d
I am wondering how can I pass a
, b
and c
to corresponding base classes' constructors.
我想知道如何将a
,b
和传递c
给相应的基类的构造函数。
采纳答案by shx2
Well, when dealing with multiple inheritance in general, your base classes (unfortunately) should be designed for multiple inheritance. Classes B
and C
in your example aren't, and thus you couldn't find a proper way to apply super
in D
.
好吧,一般来说,在处理多重继承时,您的基类(不幸的是)应该设计为多重继承。类B
和C
在您的示例中不是,因此您找不到super
在D
.
One of the common ways of designing your base classes for multiple inheritance, is for the middle-level base classes to accept extra args in their __init__
method, which they are not intending to use, and pass them along to their super
call.
为多重继承设计基类的常用方法之一是让中间层基类在其__init__
方法中接受额外的参数,它们不打算使用,并将它们传递给super
调用。
Here's one way to do it in python:
这是在python中执行此操作的一种方法:
class A(object):
def __init__(self,a):
self.a=a
class B(A):
def __init__(self,b,**kw):
self.b=b
super(B,self).__init__(**kw)
class C(A):
def __init__(self,c,**kw):
self.c=c
super(C,self).__init__(**kw)
class D(B,C):
def __init__(self,a,b,c,d):
super(D,self).__init__(a=a,b=b,c=c)
self.d=d
This can be viewed as disappointing, but that's just the way it is.
这可以被视为令人失望,但事实就是如此。
回答by Brendan Abel
Unfortunately, there is no way to make this work using super()
without changing the Base classes. Any call to the constructors for B
or C
is going to try and call the next class in the Method Resolution Order, which will always be B
or C
instead of the A
class that the B
and C
class constructors assume.
不幸的是,没有办法在super()
不改变基类的情况下使用它。该构造的任何呼吁B
或C
打算尝试拨打下一个类的方法解析顺序,这将永远是B
或C
代替A
类的B
和C
类的构造函数承担。
The alternative is to call the constructors explicitly without the use of super()
in each class.
另一种方法是显式调用构造函数,而不super()
在每个类中使用。
class A(object):
def __init__(self, a):
object.__init__()
self.a = a
class B(A):
def __init__(self, a, b):
A.__init__(self, a)
self.b = b
class C(object):
def __init__(self, a, c):
A.__init__(self, a)
self.c = c
class D(B, C):
def __init__(self, a, b, c, d):
B.__init__(self, a, b)
C.__init__(self, a, c)
self.d = d
There is still a downside here as the A
constructor would be called twice, which doesn't really have much of an effect in this example, but can cause issues in more complex constructors. You can include a check to prevent the constructor from running more than once.
这里仍然有一个缺点,因为A
构造函数会被调用两次,这在本示例中并没有太大影响,但可能会导致更复杂的构造函数出现问题。您可以包含一个检查以防止构造函数多次运行。
class A(object):
def __init__(self, a):
if hasattr(self, 'a'):
return
# Normal constructor.
Some would call this a shortcoming of super()
, and it is in some sense, but it's also just a shortcoming in multiple inheritance in general. Diamond inheritance patterns are often prone to errors. And a lot of the workarounds for them lead to even more confusing and error-prone code. Sometimes, the best answer is to try and refactor your code to use less multiple inheritance.
有些人会称这是 的缺点super()
,从某种意义上说,它也只是多重继承的缺点。菱形继承模式通常容易出错。他们的许多变通方法会导致代码更加混乱和容易出错。有时,最好的答案是尝试重构您的代码以使用更少的多重继承。