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)
-
4You are, on purpose, not returning a child from the constructor, but a parent, and then you are surprised that it acts like a parent?Gareth Latty– Gareth Latty2013年01月06日 00:02:46 +00:00Commented Jan 6, 2013 at 0:02
-
I get it, how can I then extend a class but also init it with instances of the parent returned by a function?elyase– elyase2013年01月06日 00:11:21 +00:00Commented Jan 6, 2013 at 0:11
3 Answers 3
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.
3 Comments
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)
5 Comments
p = generateParent(params); p.__class__ = Child) in the __new__ method of Child.Child.__init__ will never be called in this case, and any instance variables defined in Child.__init__will not be created, which could cause problems in methods in Child that depend on them. If you do this, write Child.__init__ to call a method like Child.addChildAttributes() that would add any special attributes, then in generateChild(), after setting p.__class__, then call p.addChildAttributes().Perhaps you want
generateParentto 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)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..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.
6 Comments
Explore related questions
See similar questions with these tags.