我正在尝试设计一种类结构,该类别允许用户定义自己的类,以超载其他类中的预定义方法。在这种情况下,用户将创建C类,以超载D。 d使用d的其他方法。我遇到的问题是如何将“值”从A和B传递到D而忽略它传递给C。我当前写的内容将产生错误,因为C没有“值”作为参数。
我知道我可以将“值”(或 *args)添加到C的init方法和超级呼叫中,但我不想知道其他类需要哪些输入才能将新类添加到A和B中。如果我交换C和DI的顺序不会出现错误,但是我不会使用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
I am trying to design a class structure that allows the user to define their own class that overloads predefined methods in other classes. In this case the user would create the C class to overload the "function" method in D. The user created C class has common logic for other user created classes A and B so they inherit from C to overload "function" but also inherit from D to use D's other methods. The issue I am having is how to pass "value" from A and B to D and ignore passing it to C. What I currently have written will produce an error as C does not have "value" as an argument.
I know that I can add "value" (or *args) to C's init method and the super call but I don't want to have to know what inputs other classes need in order to add new classes to A and B. Also, if I swap the order of C and D I won't get an error but then I don't use C's overloaded "function". Is there an obvious way around this?
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
发布评论
评论(2)
本质上,您需要做两件事来使您的
__ INT __
方法在Python中使用多个继承效果很好:** Kwargs
参数,并始终调用super() -a-super/59833056#59833056“>即使您认为自己是基类。仅仅因为您的超级类是
object
并不意味着您是__ INT __
明确地参数; 仅通过** kwargs
< /a>。您的父级不一定是您按照方法解析顺序进行的下一个类别,因此位置参数可能会传递给其他错误的__ INT __ INT __
方法。这称为“合作子分类”。让我们尝试使用您的示例代码:
演示:
请注意,
value
必须传递给a
构造函数作为关键字参数,而不是作为位置参数。还建议在调用super.value = value
super().__ init __ in __
之前设置self.value = value
。我还简化了
类C(对象):
to类C:
和super(c,self)
仅超级()
因为它们在Python 3中是等效的。Essentially, there are two things you need to do to make your
__init__
methods play nice with multiple inheritance in Python:**kwargs
parameter, and always callsuper().__init__(**kwargs)
, even if you think you are the base class. Just because your superclass isobject
doesn't mean you are last (beforeobject
) in the method resolution order.__init__
arguments explicitly; only pass them via**kwargs
. Your parent class isn't necessarily the next one after you in the method resolution order, so positional arguments might be passed to the wrong other__init__
method.This is called "co-operative subclassing". Let's try with your example code:
Demo:
Note that
value
must be passed to theA
constructor as a keyword argument, not as a positional argument. It's also recommended to setself.value = value
before callingsuper().__init__
.I've also simplified
class C(object):
toclass C:
, andsuper(C, self)
to justsuper()
since these are equivalent in Python 3.因此,我正在尝试理解A和B的点。我猜想也许您想混合超级阶级行为,有时还会有本地行为。因此,假设A只是将行为混合在一起,而B具有一些局部行为和状态。
如果您不需要自己的状态,则可能不需要
__ Init __
。因此,对于a
和c
只会省略__ INIT __
。我保留了Python2语法,假设您可能仍在使用它,但是正如另一个答案所指出的那样,Python3简化了
super()
语法,您确实应该现在使用Python3。如果交换C和D,则将更改Python方法解决顺序,这确实会更改呼叫A.功能解决的方法。
So I'm trying to understand the point of A AND B. I'm guessing that maybe you want to mix in the superclass behavior and sometimes have local behavior. So suppose A is just mixing together behaviors, and B has some local behavior and state.
If you don't need your own state, you probably don't need an
__init__
. So forA
andC
just omit__init__
.I've kept python2 syntax assuming you might still be using it, but as another answer points out, python3 simplifies
super()
syntax, and you really should be using python3 now.If you swap C and D you are changing the python method resolution order, and that will indeed change the method to which a call to A.function resolves.