Python类继承设计:假装看起来像鸭子,但不要';庸医
我今天已经搜索了几个小时,但没有得到一个最新的令人满意的明确答案 假设我们有两个特殊的类,它们都有重叠的方法名和特定的单独方法。除去不必要的部分,让我们使用以下类Python类继承设计:假装看起来像鸭子,但不要';庸医,python,python-3.x,class,multiple-inheritance,Python,Python 3.x,Class,Multiple Inheritance,我今天已经搜索了几个小时,但没有得到一个最新的令人满意的明确答案 假设我们有两个特殊的类,它们都有重叠的方法名和特定的单独方法。除去不必要的部分,让我们使用以下类 class A(): def __init__(self, a_arg1, a_arg2): self.a_arg1 = a_arg1 self.a_arg2 = a_arg2 @property def gimme_1(self): return self.a
class A():
def __init__(self, a_arg1, a_arg2):
self.a_arg1 = a_arg1
self.a_arg2 = a_arg2
@property
def gimme_1(self):
return self.a_arg1
@property
def gimme_2(self):
return self.a_arg2
@property
def prop(self):
return 'A'
而且
class B():
def __init__(self, b_arg1, b_arg2, b_arg3):
self.b_arg1 = b_arg1
self.b_arg2 = b_arg2
self.b_arg3 = b_arg3
@property
def give_1(self):
return self.b_arg1
@property
def give_2(self):
return self.b_arg2
@property
def give_3(self):
return self.b_arg3
@property
def prop(self):
return 'B'
我的目标是创建第三个类,它可以变形为其中一个,也就是说,它将拥有这两个类所拥有的所有方法,并将其视为它们中的一个。这就是问题标题的动机
class C(A, B):
def __init__(self, some_list):
self.some_list = some_list
@property
def gimme_1(self):
return self.some_list[0]
@property
def gimme_2(self):
return self.some_list[1]
@property
def give_1(self):
return self.some_list[0] ** 2
@property
def give_2(self):
return self.some_list[1] ** 2
@property
def give_3(self):
return self.some_list[2]
@property
def prop(self):
return 'C'
具体问题:
super()
李>
isinstance(x,A)
或isinstance(x,B)
类型的查询。是否有任何最佳实践不鼓励此类使用?注意,在我的例子中,pythonicduck类型对我来说真的不是那么相关。对于不同的计算算法,必然会出现很多分支。因此,我实际上是将类用作数据绑定容器,而不是将它们用作状态记录器。换句话说,它们的实例数据几乎没有变化。但它们的数据在不同的分支中使用,这取决于它们是哪个类。因此,获得合适的对象对我来说至关重要与其重写方法,为什么不利用继承的好处呢?让父级
\uuuu init\uuuu
负责设置实例值,并让它们提供方法实现
class C(A, B):
def __init__(self, arg1, arg2, arg3):
A.__init__(self, arg1, arg2)
B.__init__(self, arg1**2, arg2**2, arg3)
@property
def prop(self):
return 'C'
与其重写方法,为什么不利用继承的好处呢?让父级
\uuuu init\uuuu
负责设置实例值,并让它们提供方法实现
class C(A, B):
def __init__(self, arg1, arg2, arg3):
A.__init__(self, arg1, arg2)
B.__init__(self, arg1**2, arg2**2, arg3)
@property
def prop(self):
return 'C'
你说“变形成这样”是什么意思?两者都是。是的,您应该使用
super
来确保在子类化时调用所有相关方法。或者,如果你不想让它成为一个子类,为什么要子类化?@jornsharpe如果你要求a
或B
拥有的任何方法,从C
,它的响应将与a
或B
一样。即使我已经覆盖了所有的方法,我仍然需要调用super吗?duck类型表示您不关心对象是否是某个对象的子类,只关心它是否具有相关的属性。目前还不清楚您实际上想要实现什么,但您可能不需要继承。你真的试过这些吗?发生了什么事?@Jornsharpe看一看问题2。你什么意思?这是我简化的一个实际问题。我不知道该注意什么。这就是为什么我问你“变形成这些东西”是什么意思?两者都是。是的,您应该使用super
来确保在子类化时调用所有相关方法。或者,如果你不想让它成为一个子类,为什么要子类化?@jornsharpe如果你要求a
或B
拥有的任何方法,从C
,它的响应将与a
或B
一样。即使我已经覆盖了所有的方法,我仍然需要调用super吗?duck类型表示您不关心对象是否是某个对象的子类,只关心它是否具有相关的属性。目前还不清楚您实际上想要实现什么,但您可能不需要继承。你真的试过这些吗?发生了什么事?@Jornsharpe看一看问题2。你什么意思?这是我简化的一个实际问题。我不知道该注意什么。这就是为什么我要问重写的原因是C
的行为实际上不像A
或B
,因此我试图得到一个泛型类,它的行为仍然像A或B,但不会像它们那样。因此,我不会使用A
或B
中的任何一种,但如果需要,它将以A
或B
的格式提供必要的输出。这通常对您的设计不是一个好迹象。您应该后退一步,尝试解决这个问题,这样您的类型才有意义。一般来说,继承应满足“是一种”关系。如果我有一个classCar
,和一个子类Ford(Car)
,这是有道理的,因为每一辆Ford也是一辆车。如果您有一个Cat
类,并且您想编写一个Dog
类,那么使用继承是没有意义的,即使这两个类在很大程度上是相似的。(您将创建一个Animal
父类)。这些显然是简单化的例子,但我希望它们能有所帮助。它们实际上满足了你的汽车类比。但是想象一下,我在C
上安装了一台电动发动机。在你的类比中,我有两个类汽车和卡车。而C
变成了电动汽车或卡车。他们旧的基于汽油的计算将不再有意义,但我想在任何现有的计算中使用电动汽车或卡车。然而,我必须告诉我的旧代码库,这仍然是一辆汽车,并询问你想从中得到什么。在那里,我将有一个单独的、抽象的引擎
类,可以细分为电动和汽油(以及氢等)引擎。基本上,与这些可变元素交互的部分不应该关心它们正在使用哪个实现。如果您不熟悉它们,您可能想了解Java接口。Python没有直接的类比,但它是设计程序的一种有用方法。那么,回答你的问题,答案是否定的。像这样使用继承不会破坏任何东西,而且(据我所知)Python的任何内部机制都不会受到影响。重写的原因是C
实际上没有影响