我想做这样的事情:
class A:
def methodA(self):
return 5
class B:
def methodB(self):
return 10
class X(...):
def __init__(self, baseclass):
if baseclass =='A' : derive X from A
elif baseclass == 'B' : derive X from B
else: raise Exception("Not supported baseclass %s!" % (baseclass))
def methodX(self):
return 42
X('A').methodA() # returns 5
X('A').methodX() # returns 42
X('A').methodB() # methodB not defined
X('B').methodB() # returns 10
X('B').methodX() # returns 42
X('A').methodA() # methodA not defined
我该如何实现?
答案 0 :(得分:3)
如果要将methodX
添加到现有类,可以考虑多重继承:
class A:
def methodA(self):
return 5
class B:
def methodB(self):
return 10
class X():
@classmethod
def new(cls, baseclass):
if baseclass == A:
return AX()
elif baseclass == B:
return BX()
else: raise Exception("Not supported baseclass %s!" % str(baseclass))
def methodX(self):
return 42
class AX(A, X):
pass
class BX(B, X):
pass
您可以向X.new
添加args和kwargs,并将它们传递给特定的构造函数。以下是您的测试结果(我在您的问题中更正了最后一项):
>>> ax = X.new(A)
>>> ax.methodA() # returns 5
5
>>> ax.methodX() # returns 42
42
>>> ax.methodB() # methodB not defined
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: AX instance has no attribute 'methodB'
>>> bx = X.new(B)
>>> bx.methodB() # returns 10
10
>>> bx.new(B).methodX() # returns 42
42
>>> bx.new(B).methodA() # methodA not defined
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: BX instance has no attribute 'methodA'
答案 1 :(得分:2)
您应该定义两个类X
和Y
,以及一个工厂方法来实例化X或Y,具体取决于参数。
通常,您尝试实施的行为有点令人困惑。当您创建实例(即X(...)
所做的)时,您应该获得X
的实例,并且类的实例应该具有相同的属性。这是课程存在的主要原因之一。
示例:
class A:
def methodA(self):
return 5
class B:
def methodB(self):
return 10
def x(class_name):
name2class = {"A":A, "B":B}
return name2class[class_name]()
for name in ["A","B","C"]:
instance = x(name)
print name, instance
将打印
A <__main__.A instance at 0x022C8D50>
B <__main__.B instance at 0x022C8DF0>
Traceback (most recent call last):
File ".../14834949.py", line 21, in <module>
instance = x(name)
File ".../14834949.py", line 18, in x
return name2class[class_name]()
KeyError: 'C'