1

我想做这样的事情:

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

我该如何实施?

4

2 回答 2

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

您可以添加 args 和 kwargsX.new并将它们传递给特定的构造函数。这是您的测试的输出(我更正了您问题中的最后一个):

>>> 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'
于 2013-02-12T17:54:14.833 回答
2

您应该定义两个类XY,以及一个工厂方法来实例化 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'
于 2013-02-12T14:39:43.003 回答