Python - 选择要继承的 class
Python - Choose which class to inherit
我想制作两个 classes A 和 B,其中 B 是 A 的轻微但重要的变体,然后制作第三个 class C 可以继承 A或 B 并为它们添加功能。问题是,如何让C根据我的喜好继承A或B?
为了让事情更清楚,假设我有这段代码:
class A:
def __init__(self, x, y):
self.x = x
self.y = y
def first(self):
return do_something(1)
def second(self):
return do_something(2)
def third(self):
return do_something(3)
def start(self):
self.first()
self.second()
self.third()
class B(A):
def __init__(self, x, y, z):
super().__init__(x, y)
self.z = z
def second(self):
super().second()
do_stuff()
def third(self):
do_other_stuff()
这是我使用的代码的一个非常简化的版本。特别地,A 代表制造系统的模拟器,而 B 代表同一制造系统的模拟器,但修改了主机床的行为。
现在,我想要的是添加代码来计算一些统计数据。它的作用是这样的:
class C(A):
def __init__(self, *args):
super().__init__(*args)
self.stat = 0
def second(self):
super().second()
self.stat += 1
def third(self):
super().third()
self.stat *= 3
问题是 class C 的工作方式完全相同,无论是我继承 class A(如前面的清单)还是 class B(完全相同的代码,作为第一行 class C(B):
我该怎么做?还是我使用了一种不可行的方式?我认为一个理想的解决方案是在我初始化 C 时能够选择 class 继承 A 或 B。或者,也许,能够将 class 传递给 class C ]继承。
我做了一些研究,我也发现了聚合的可能性(我以前不知道),但我不认为它真的有用。最后一点,请注意 class A 可能有多达 20-30 个方法,当我使用 class C 时,我想要 class A(或 B,取决于它继承的)与以前一样工作,中间添加了 C 块。
P.S。我正在寻找一种可能优雅的、没有大量代码的 "pythonic" 方法来做到这一点。我也非常期待关于您认为可以做得更好的所有事情的建议。最后,我完全可以修改 class C,但是 class A 和 B 必须保持不变(除了小的改动)。
您可以使用新式classes及其方法解析顺序.
考虑这些定义:
class A(object):
def __init__(self, x):
pass
def foo(self):
print "A"
class B(object):
def __init__(self, x, y):
pass
def foo(self):
print "B"
您可以构建一个 mixin,旨在向 A
或 B
添加功能:
class Cmix(object):
def foo(self):
super(Cmix, self).foo()
print "mix"
并分别继承自 Cmix
和 A
(或 B
):
class CA(Cmix, A):
pass
class CB(Cmix, B):
pass
最后,你可以写一个方便的函数来根据参数的数量在CA
和CB
之间进行选择:
def C(*args):
if len(args) == 1:
return CA(*args)
else:
return CB(*args)
现在我们有
C(1).foo()
# A
# mix
C(1, 2).foo()
# B
# mix
请注意,C
不是真正的 class,例如,您不能将其用作 isinstance
中的第二个参数。
我想制作两个 classes A 和 B,其中 B 是 A 的轻微但重要的变体,然后制作第三个 class C 可以继承 A或 B 并为它们添加功能。问题是,如何让C根据我的喜好继承A或B?
为了让事情更清楚,假设我有这段代码:
class A:
def __init__(self, x, y):
self.x = x
self.y = y
def first(self):
return do_something(1)
def second(self):
return do_something(2)
def third(self):
return do_something(3)
def start(self):
self.first()
self.second()
self.third()
class B(A):
def __init__(self, x, y, z):
super().__init__(x, y)
self.z = z
def second(self):
super().second()
do_stuff()
def third(self):
do_other_stuff()
这是我使用的代码的一个非常简化的版本。特别地,A 代表制造系统的模拟器,而 B 代表同一制造系统的模拟器,但修改了主机床的行为。
现在,我想要的是添加代码来计算一些统计数据。它的作用是这样的:
class C(A):
def __init__(self, *args):
super().__init__(*args)
self.stat = 0
def second(self):
super().second()
self.stat += 1
def third(self):
super().third()
self.stat *= 3
问题是 class C 的工作方式完全相同,无论是我继承 class A(如前面的清单)还是 class B(完全相同的代码,作为第一行 class C(B):
我该怎么做?还是我使用了一种不可行的方式?我认为一个理想的解决方案是在我初始化 C 时能够选择 class 继承 A 或 B。或者,也许,能够将 class 传递给 class C ]继承。
我做了一些研究,我也发现了聚合的可能性(我以前不知道),但我不认为它真的有用。最后一点,请注意 class A 可能有多达 20-30 个方法,当我使用 class C 时,我想要 class A(或 B,取决于它继承的)与以前一样工作,中间添加了 C 块。
P.S。我正在寻找一种可能优雅的、没有大量代码的 "pythonic" 方法来做到这一点。我也非常期待关于您认为可以做得更好的所有事情的建议。最后,我完全可以修改 class C,但是 class A 和 B 必须保持不变(除了小的改动)。
您可以使用新式classes及其方法解析顺序.
考虑这些定义:
class A(object):
def __init__(self, x):
pass
def foo(self):
print "A"
class B(object):
def __init__(self, x, y):
pass
def foo(self):
print "B"
您可以构建一个 mixin,旨在向 A
或 B
添加功能:
class Cmix(object):
def foo(self):
super(Cmix, self).foo()
print "mix"
并分别继承自 Cmix
和 A
(或 B
):
class CA(Cmix, A):
pass
class CB(Cmix, B):
pass
最后,你可以写一个方便的函数来根据参数的数量在CA
和CB
之间进行选择:
def C(*args):
if len(args) == 1:
return CA(*args)
else:
return CB(*args)
现在我们有
C(1).foo()
# A
# mix
C(1, 2).foo()
# B
# mix
请注意,C
不是真正的 class,例如,您不能将其用作 isinstance
中的第二个参数。