Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python“;“新风格”;多重继承与多个_init__参数相结合_Python_Oop_Inheritance_Multiple Inheritance - Fatal编程技术网

Python“;“新风格”;多重继承与多个_init__参数相结合

Python“;“新风格”;多重继承与多个_init__参数相结合,python,oop,inheritance,multiple-inheritance,Python,Oop,Inheritance,Multiple Inheritance,据我所知,如果所有类都使用“新样式”,则会发生以下情况: class A(object): def __init__(self): print("Entering A") super().__init__() print("Leaving A") class B(object): def __init__(self): print("Entering B"

据我所知,如果所有类都使用“新样式”,则会发生以下情况:

class A(object):
    def __init__(self):
        print("Entering A")
        super().__init__()
        print("Leaving A")

class B(object):
    def __init__(self):
        print("Entering B")
        super().__init__()
        print("Leaving B")

class C(A, B):
    def __init__(self):
        print("Entering C")
        super().__init__()
        print("Leaving C")

c = C()
在理解了
super
使用原始对象的MRO(
c
)之后,可以理解为什么
进入/离开
是这样的。但是如果我需要将一些特定的参数传递给
A
B
,但是在
C
中接收参数的顺序与
A
B
不同,该怎么办呢

class A(object):
    def __init__(self, x1, x2):
        print(f"Entering A [x1={x1}, x2={x2}]")
        super().__init__()
        print("Leaving A")

class B(object):
    def __init__(self, y1, y2):
        print(f"Entering B [y1={y1}, y2={y2}]")
        super().__init__()
        print("Leaving B")

class C(A, B):
    def __init__(self, x1, y1, x2, y2):
        print(f"Entering C [x1={x1}, y1={y1}, x2={x2}, y2={y2}]")
        super().__init__()
        print("Leaving C")

c = C('x1', 'y1', 'x2', 'y2')
我可以想一整天只通过
kwargs
,但我觉得可能有更好的方法

另外,如果
B
是库的一部分,因此我们不能更改它它使用位置参数,而不是
kwargs
,该怎么办?在这种情况下,我能做什么,因为我认为手动处理MRO不是一个好主意,但同时
B
的构造函数不会接受
kwargs


解决上述问题的正确方法是什么?

好的,这将不再适用于评论,但这里似乎存在一些误解

用于:

这将产生:

d = D(2)
print(d.attr1)  # prints: 1
因为通过
super()

或者引用文档中的内容:

返回一个代理对象,该对象将方法调用委托给类型为的父类或同级类。这对于访问类中已重写的继承方法非常有用

也就是说,您“只”获得(可能绑定)要调用的解析方法。不多不少。它不会整理你传递的任何论点。因此,您的示例实际上不起作用,因为两个父构造函数都需要一个实例和两个以上的参数

在你的例子中,你可以说:

class A:
    def __init__(self, x1, x2):
        print(f"Entering A [x1={x1}, x2={x2}]")
        print("Leaving A")

class B:
    def __init__(self, y1, y2):
        print(f"Entering B [y1={y1}, y2={y2}]")
        print("Leaving B")

class C(A, B):
    def __init__(self, x1, y1, x2, y2):
        print(f"Entering C [x1={x1}, y1={y1}, x2={x2}, y2={y2}]")
        A.__init__(self, x1, x2)
        B.__init__(self, y1, y2)
        print("Leaving C")
因为您使用相应的特定参数调用每个特定的父构造函数。文档(第二个具有多重继承的常见用例的下面几段)也包含关于以下内容的提示:

良好的设计要求该方法在每种情况下都具有相同的调用签名(因为调用顺序是在运行时确定的,因为该顺序适应类层次结构中的更改,并且因为该顺序可以包括在运行前未知的同级类)


也就是说,你得到一个代理来调用这个方法。。。你用它的参数来称呼它。。。它必须是一个固定/稳定的集合,因为您无法预先确定通过该代理访问的是哪种方法。

我感到困惑,您可能想调用父级构造函数,而不知道该构造函数预先具有哪个父级和什么签名?如果需要灵活性,您可以使用
kwargs
来实现这一点,并获得所需的位,但“正确”的方法是调用
A.\uu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。没有魔法,没有歧义。@OndrejK。但这不是“旧式”吗?我了解你如何使用这种风格,但这意味着“新风格”应该能够做“旧风格”所能做的一切,并提供一些额外的好处(在本例中是更健壮的分解代码)。对于你所描述的,这与“旧风格”无关,但是关于设计/意图。@OndrejK。如果这种“新风格”不能执行与“旧风格”相同的任务,那么你能解释一下为什么会引入这种“新风格”吗?
d = D(2)
print(d.attr1)  # prints: 1
class A:
    def __init__(self, x1, x2):
        print(f"Entering A [x1={x1}, x2={x2}]")
        print("Leaving A")

class B:
    def __init__(self, y1, y2):
        print(f"Entering B [y1={y1}, y2={y2}]")
        print("Leaving B")

class C(A, B):
    def __init__(self, x1, y1, x2, y2):
        print(f"Entering C [x1={x1}, y1={y1}, x2={x2}, y2={y2}]")
        A.__init__(self, x1, x2)
        B.__init__(self, y1, y2)
        print("Leaving C")