在runtim决定基类

2024-09-30 06:32:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我想这样做:

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

我该如何实现这一点?你知道吗


Tags: fromselfreturnifinitdefnotclass
2条回答

如果要将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

您可以将arg和kwarg添加到X.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'

应该定义两个类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'

相关问题 更多 >

    热门问题