选择性继承Python

时间:2012-09-19 09:23:23

标签: python

我正在制作一个使用类的python程序,我希望一个类只选择性地从另一个类继承,例如:

class X(object):
    def __init__(self):
        self.hello = 'hello'

class Y(object):
    def __init__(self):
        self.moo = 'moo'

class Z():
    def __init__(self, mode):
        if mode == 'Y':
             # Class will now Inherit from Y
        elif mode == 'X':
             # Class will now Inherit for X

如果不另外上课,我怎么能这样做?

4 个答案:

答案 0 :(得分:3)

在Python中,可以在运行时创建类:

class X(object):
    def __init__(self):
        self.hello = 'hello'

class Y(object):
    def __init__(self):
        self.moo = 'moo'

def create_class_Z(mode):
    base_class = globals()[mode]
    class Z(base_class):
        def __init__(self):
            base_class.__init__(self)
    return Z

ZX = create_class_Z('X')
zx = ZX()
print(zx.hello)

ZY = create_class_Z('Y')
zy = ZY()
print(zy.moo)

答案 1 :(得分:2)

您可以overriding __new__执行此操作并更改传入的cls(您通过附加XY作为基类来创建新类型):

class X(object):
    def __init__(self):
        self.hello = 'hello'

class Y(object):
    def __init__(self):
        self.moo = 'moo'

class Z(object):
    def __new__(cls, mode):
        mixin = {'X': X, 'Y': Y}[mode]
        cls = type(cls.__name__ + '+' + mixin.__name__, (cls, mixin), {})
        return super(Z, cls).__new__(cls)
    def __init__(self, mode, *args, **kwargs):
        super(Z, self).__init__(*args, **kwargs)

请注意,您需要使用Z.__new__绕过super以避免无限递归;这是__new__特殊覆盖方法的标准模式。

答案 2 :(得分:0)

我认为您最好在Z中定义两个成员,一个是X的类实例,另一个是Y的实例。您可以在使用不同模式时获取存储在这些实例中的相关信息。

答案 3 :(得分:0)

使用type的解决方案:

class _Z(): pass #rename your class Z to this

def Z(mode): #this function acts as the constructor for class Z
    classes = {'X': X, 'Y': Y, 'Foo': Bar} #map the mode argument to the base cls
    #create a new type with base classes Z and the class determined by mode
    cls = type('Z', (_Z, classes[mode]), {})
    #instantiate the class and return the instance
    return cls()