我有一个孩子类,其中两个父类的函数名称相同。
我需要(根据创建的对象类型)在构造函数(__init__
中)确定子对象需要调用哪个父类的函数。有没有一种方法可以将默认函数调用动态链接/切换到父对象之一。下面给出了示例代码。我不想使用对象容器,因为它很难维护和重构。
class Square:
def perform(self, num):
print(num * num)
class Cube:
def perform(self, num):
print(num * num * num)
class Exponent(Square, Cube):
def __init__(self, type):
if type == 'square':
# inherit default functions from square <--- ??
else:
# inherit default functions from cube <--- ??
square = Square() # <-- i don't want to do this
cube = Cube() # <-- i don't want to do this
Exponent('cube').perform(2) # --> should print '8'
Exponent('square').perform(2) # --> should print '4'
Exponent('cube').cube.perform(2) # <-- i don't want to do this
Exponent('square').square.perform(2) # <-- i don't want to do this
下面给出了一种方法,但是涉及到复制所有父类函数,这太过分了:
class a:
def x (self):
print('a')
class b:
def x (self):
print('b')
class c(a,b):
def __init__(self, type_):
if type_ == 'a':
self.ref = a
else:
self.ref = b
def x(self):
self.ref.x(self)
c('a').x()
c('b').x()
答案 0 :(得分:3)
Python提供了很多灵活性,但是您正在与该语言提供的类机制进行对抗。无法“不费吹灰之力”地完成此操作,因为您将在该语言提供的功能之上实现自己的机制。老实说,只需忘记使用多重继承,因为继承不是您要描述的,您需要一个代理对象来委派给适当的对象。根据您的具体情况,这看起来可能会有所不同,但这可以帮助您:
In [1]: class A:
...: def x (self):
...: print('a')
...:
...: class B:
...: def x (self):
...: print('b')
...:
...: class C:
...: def __init__(self, type_, *args, **kwargs):
...: self.__wrapped = type_(*args, **kwargs)
...: def __getattr__(self, attr):
...: return getattr(self.__wrapped, attr)
...:
...:
In [2]: C(A).x()
a
In [3]: C(B).x()
b
注意,C.__init__
的实现方式是将第一个参数之后的所有内容传递给委托类型的构造函数。
答案 1 :(得分:2)
我会为此戳戳。 工厂功能而不是子类会满足您的需求吗?如果没有,请评论您想要的内容,我也许可以找到一种方法。
class Square:
def perform(self, num):
print(num * num)
class Cube:
def perform(self, num):
print(num * num * num)
def Exponent(type):
if type == 'square':
return Square()
else:
return Cube()
Exponent('cube').perform(2)
Exponent('square').perform(2)
如果您希望Exponent
返回的所有内容都具有某些常见行为,则可以为此定义另一个类。
class Square:
def perform(self, num):
print(num * num)
class Cube:
def perform(self, num):
print(num * num * num)
class ExponentType:
def child_perform(self, num):
print(num ** 4)
class ExponentSquare(ExponentType, Square): pass
class ExponentCube(ExponentType, Cube): pass
def Exponent(type):
if type == 'square':
return ExponentSquare()
else:
return ExponentCube()
Exponent('cube').perform(2)
Exponent('square').perform(2)
Exponent('cube').child_perform(2)
Exponent('square').child_perform(2)