Can I choose the parent class of a class from a fixed set of parent classes conditionally in the __init__ function?

前端 未结 2 1995
孤街浪徒
孤街浪徒 2020-12-22 00:40

I have a child class with two parents with identical function names.

I need to decide (based on type of object being created) within the constructor (__init__<

相关标签:
2条回答
  • 2020-12-22 01:07

    Python offers a lot of flexibility, but you're working against the class mechanisms the language offers. there is no way to do this "with out any additional effort" since you will be implementing your own mechanisms on top of what the language offers. Honestly, just forget about using multiple inheritance, because inheritance is not what you are describing, you want a proxy object that delegates to the appropriate object. Depending on your specific circumstances, this could look different, but this will get you going:

    In [1]: class A:
       ...:     def x (self):
       ...:         print('a')
       ...:
       ...: class B:
       ...:     def x (self):
       ...:         print('b')
       ...:
       ...: class C:
       ...:     def __init__(self, type_, *args, **kwargs):
       ...:         self.__wrapped = type_(*args, **kwargs)
       ...:     def __getattr__(self, attr):
       ...:         return getattr(self.__wrapped, attr)
       ...:
       ...:
    
    In [2]: C(A).x()
    a
    
    In [3]: C(B).x()
    b
    

    Note, the way C.__init__ is implemented, everything after the first argument is passed to the delegated type's constructor.

    0 讨论(0)
  • 2020-12-22 01:09

    I will take a jab at this. Would a factory function instead of a child class satisfy your need? If it doesn't, comment what you want and I might be able to find a way.

    class Square: 
        def perform(self, num):
            print(num * num)
    
    class Cube: 
        def perform(self, num):
            print(num * num * num)
    
    def Exponent(type):
        if type == 'square':
            return Square()
        else:
            return Cube()
    
    Exponent('cube').perform(2)
    Exponent('square').perform(2)
    

    If you want everything returned by Exponent to have some common behavior, then you can define another class for that.

    class Square: 
        def perform(self, num):
            print(num * num)
    
    class Cube: 
        def perform(self, num):
            print(num * num * num)
    
    class ExponentType:
        def child_perform(self, num):
            print(num ** 4)
    
    class ExponentSquare(ExponentType, Square): pass
    class ExponentCube(ExponentType, Cube): pass
    
    def Exponent(type):
        if type == 'square':
            return ExponentSquare()
        else:
            return ExponentCube()
    
    Exponent('cube').perform(2)
    Exponent('square').perform(2)
    Exponent('cube').child_perform(2)
    Exponent('square').child_perform(2)
    
    0 讨论(0)
提交回复
热议问题