我正在尝试设计一个类结构,允许用户定义自己的类,以重载其他类中的预定义方法。在这种情况下,用户将创建 C 类来重载 D 中的“函数”方法。用户创建的 C 类与其他用户创建的类 A 和 B 具有共同的逻辑,因此它们继承自 C 来重载“函数”,但也继承自D使用D的其他方法。我遇到的问题是如何将“值”从 A 和 B 传递到 D 并忽略将其传递给 C。我当前编写的内容将产生错误,因为 C 没有“值”作为参数。
我知道我可以向 C 的 init 方法和 super 调用添加“值”(或 *args),但我不想知道其他类需要什么输入才能向 A 和 B 添加新类。另外,如果我交换 C 和 D 的顺序,我不会收到错误,但我不会使用 C 的重载“函数”。有一个明显的方法可以解决这个问题吗?
class D(SomethingElse):
def __init__(self, value, **kwargs):
super(D, self).__init__(**kwargs)
self.value = value
def function(self):
return self.value
def other_method(self):
pass
class C(object):
def __init__(self):
super(C, self).__init__()
def function(self):
return self.value*2
class B(C, D):
def __init__(self, value, **kwargs):
super(B, self).__init__(value, **kwargs)
class A(C, D):
def __init__(self, value, **kwargs):
super(A, self).__init__(value, **kwargs)
a = A(3)
print(a.function())
>>> 6
本质上,您需要做两件事来使您的__init__
方法在 Python 中与多重继承配合得很好:
- 总是采取一个
**kwargs
参数,并始终调用super().__init__(**kwargs)
, 即使你认为自己是底层。只是因为你的超类是object
并不意味着你是最后一个(之前object
) 在里面方法解析顺序.
- 不要通过你的父类
__init__
明确论证;仅通过它们传递**kwargs。您的父类不一定是方法解析顺序中您之后的下一个类,因此位置参数可能会传递给错误的其他类__init__
method.
这称为“合作子类化”。让我们尝试一下您的示例代码:
class D:
def __init__(self, value, **kwargs):
self.value = value
super().__init__(**kwargs)
def function(self):
return self.value
class C:
# add **kwargs parameter
def __init__(self, **kwargs):
# pass kwargs to super().__init__
super().__init__(**kwargs)
def function(self):
return self.value * 2
class B(C, D):
# don't take parent class's value arg explicitly
def __init__(self, **kwargs):
# pass value arg via kwargs
super().__init__(**kwargs)
class A(C, D):
# don't take parent class's value arg explicitly
def __init__(self, **kwargs):
# pass value arg via kwargs
super().__init__(**kwargs)
Demo:
>>> a = A(value=3)
>>> a.value
3
>>> a.function()
6
注意value
必须传递给A
构造函数作为关键字参数,而不是作为位置参数。还建议设置self.value = value
打电话之前super().__init__
.
我也简化了class C(object):
to class C:
, and super(C, self)
只是super()
因为它们在 Python 3 中是等效的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)