wong2
wong2

Reputation: 35720

Turn a instance to its class's child type (calling super for classmethod)

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

Answers (2)

ndpu
ndpu

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

user2357112
user2357112

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

Related Questions