代码的直接问题是
ClassC
继承自
GraphicsWindow
作为它的第一个基类,
ClassA
是第二个基类。当你打电话
super
,只有一个被调用(
图形窗口
)如果它不是设计用于多重继承(看起来是这样),它可能不会调用
超级的
自身或不可能传递
甲级
期待。
仅仅改变基类的顺序就足以让它工作。python保证基类的调用顺序与它们在
class
语句(如果以后发生更多继承,则可以在MRO中的其他类之间插入)。自从
ClassA.__init__
打电话来
超级的
,应该效果更好!
做起来可能很难
__init__
方法使用多重继承,即使所有涉及的类都设计为使用它。这就是为什么位置参数经常被避免,因为它们的顺序可能变得非常混乱(因为子类只能在父类的位置参数之前添加位置参数,除非它们想重复所有的名称)。使用关键字参数绝对是一种更好的方法。
但是,您所拥有的代码使处理关键字参数变得比应该的复杂一些。不需要显式地创建字典来传递
**kwargs
语法,也不需要从接受的dict中提取关键字值。
**夸尔格斯
争论。通常每个函数都应该命名它所接受的参数,并且只使用
**夸尔格斯
对于未知参数(mro中的其他类可能需要)。下面是它的样子:
class Base1:
def __init__(self, *, arg1, arg2, arg3, **kwargs): # the * means the other args are kw-only
super().__init__(**kwargs) # always pass on all unknown arguments
... # use the named args here (not kwargs)
class Base2:
def __init__(self, *, arg4, arg5, arg6, **kwargs):
super().__init__(**kwargs)
...
class Derived(Base1, Base2):
def __init__(self, *, arg2, arg7, **kwargs): # child can accept args used by parents
super().__init__(arg2=arg2+1, arg6=3, **kwargs) # it can then modify or create from
... # scratch args to pass to its parents
obj = Derived(arg1=1, arg2=2, arg3=3, arg4=4, arg5=5, arg7=7) # note, we've skipped arg6
# and Base1 will get 3 for arg2
但我也会认真考虑遗产在你的情况下是否有意义。将两个基类中的一个封装在子类中,而不是继承自子类,这可能更有意义。也就是说,你只能从
甲级
或
图形窗口
,并将另一个实例存储在
C类
是的。(您甚至可以从两个基类都继承,并将它们都封装起来。)封装通常比继承更容易推理和正确处理。