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 と kwargs を追加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'
于 2013-02-12T17:54:14.833 に答える
2

パラメータに応じて X または Y のいずれかをインスタンス化するには、2 つのクラスXと、および factory-method を定義する必要があります。Y

一般に、実装しようとする動作はやや混乱します。インスタンスを作成するとき (これが実行することですX(...)) のインスタンスを取得する必要がXあり、クラスのインスタンスは同じ属性を持つ必要があります。それが、クラスが存在する主な理由の 1 つです。

例:

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 に答える