Init child with Parent instance

2019-07-21 09:51发布

问题:

I have a function which return instances of the class Parent:

def generateParent():
   do_stuff
   return Parent(some_parameters)

Now I want to init a subclass of Parent with the results of a call to generateParent():

class Child(Parent):
    def __new__():
        return generateParent(some_other_parameters) 

The problem is, when I override some methods from Parent in Child and then call them in instances of Child in my program, the original Parent method gets called instead of the new one from Child. Am I doing something wrong here? Am I using the correct design here for my task?

EDIT: I don't have access neither to Parent nor generateParent()

Solution(thanks to @Paul McGuire's answer):

class Child(object):
    def __init__(self):
        self.obj = generateParent()

    def __getattr__(self, attr):
        return getattr(self.obj, attr)

回答1:

Since generateParent is not your code, then instead of inheritance, you might want to use containment and delegation. That is, instead of defining a subclass, define a wrapper class that contains the generated object, forwards method calls to it when needed, but can add new behavior or modified behavior in the wrapper.

In this question, the OP had a similar situation, having a class generated in a libary, but wanting to extend the class and/or modify some behavior of the class. Look at how I added a wrapper class in that question, and you might consider doing something similar here.



回答2:

Here's one way to do it:

def generateChild(params):
    p = generateParent(params)
    p.__class__ = Child
    return p

class Child(Parent):
    # put method overrides etc here

childinstance = generateChild(some_params)


回答3:

  1. Perhaps you want generateParent to be able to make instances of other classes:

    def generateParent(cls=Parent):
        do_stuff
        return cls(some_parameters)
    

    Now this will make a Child object:

    child = generateParent(Child)
    
  2. Or perhaps you want Parent and all of its derived classes to use common initialization code?

    class Parent(object):
        def __init__(self):
            do_stuff
            # init from some_parameters
    
    class Child(Parent):
        # blah..
    
  3. Make your Child object able to copy information from a created Parent object:

    class Child(Parent):
        def __init__(self):
            model_parent = generateParent()
            self.a = model_parent.a
            self.b = model_parent.b
            # etc.