Reputation: 35720
class Parent:
def __init__(self, name):
self.name = name
@classmethod
def get(cls, name):
return cls(name)
def greeting(self):
print 'Hello ' + self.name
class Child(Parent):
@classmethod
def get(cls, name):
p = Parent.get(name)
p.full_name = 'James ' + name
return p
def greeting(self):
print 'Bye ' + self.full_name
as you can see, I added an attribute full_name
in the Child
's get
method to the instance of Parent, the problem is, now the instance if still in the type of Parent
, how could I turn it into Child
?
Upvotes: 2
Views: 157
Reputation: 22561
Make object as Parent base class:
class Parent(object):
and then change this line in Child p = Parent.get(name)
to:
p = super(Child, cls).get(name)
This way super(Child, cls).get(name)
will bound cls (Child) to parent get
method, so in result Parent.get
will be called with Child
class as cls
parameter. Of course to make this work you need new style classes that why object
should be in Parent
bases!
Upvotes: 1
Reputation: 280465
You don't need to change the type of the returned object. What you need to do is call the parent class's implementation of the method with the same cls
the child class's method is using. This is one of the things super
is for. First, you'll need to make sure you're using new-style classes:
class Parent(object):
# continue as usual
Python has two implementations of the class system, because they didn't get it right the first time. Always inherit from object
if you're not inheriting from anything else, to make sure you're using the newer, better system.
Now, super
. Instead of using Parent.get(name)
, use a super
call:
p = super(Child, cls).get(name)
p
will have the correct type, since cls
in the parent's method was the same class as cls
in the child's method. (Note that if you later added a Grandchild
class, this line would produce Grandchild
objects instead of Child
objects. This is most likely the right behavior.)
Upvotes: 1