Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.4k views
in Technique[技术] by (71.8m points)

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

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__) that which parent class' functions need to be called by the object of child. Is there a way to dynamically link/switch default function calls to that of one of the parents. Sample code given below. I don't want to use container-ship of objects as its very difficult to maintain and refactor.

class Square: 
 def perform(self, num):
     print(num * num)

class Cube: 
 def perform(self, num):
     print(num * num * num)

class Exponent(Square, Cube):
 def __init__(self, type):
    if type == 'square':
        # inherit default functions from square <--- ??
    else:
        # inherit default functions from cube <--- ??

    square = Square()  # <-- i don't want to do this
    cube = Cube()      # <-- i don't want to do this

Exponent('cube').perform(2)    # --> should print '8'
Exponent('square').perform(2)  # --> should print '4'

Exponent('cube').cube.perform(2)      # <-- i don't want to do this
Exponent('square').square.perform(2)  # <-- i don't want to do this

One way is given below but involves duplicating all parent class functions which is way too much overkill:

class a:
    def x (self):
        print('a')

class b:
    def x (self):
        print('b')

class c(a,b):
    def __init__(self, type_):
        if type_ == 'a':
            self.ref = a
        else:
            self.ref = b

    def x(self):
        self.ref.x(self)


c('a').x()
c('b').x()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...