将实例转换为其类的子类型(为classmethod调用super)

时间:2014-01-17 09:20:29

标签: python oop

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

正如您所看到的,我在full_name的{​​{1}}方法中向Parent的实例添加了一个属性Child,问题是,现在该实例仍然在类型中get,我怎么能把它变成Parent

2 个答案:

答案 0 :(得分:1)

将对象设为父基类:

class Parent(object):

然后将子p = Parent.get(name)中的这一行更改为:

p = super(Child, cls).get(name)

这样super(Child, cls).get(name)会将cls(Child)绑定到父get方法,因此结果Parent.get将使用Child类作为cls参数调用。当然为了完成这项工作,您需要新的样式类,为什么object应该在Parent基础中!

答案 1 :(得分:1)

您无需更改返回对象的类型。您需要做的是使用子类的方法使用的相同cls调用父类的方法实现。这是super所针对的事情之一。首先,您需要确保使用新式类:

class Parent(object):
    # continue as usual

Python有两个类系统的实现,因为它们第一次没有正确使用它。如果您没有继承其他任何内容,请始终从object继承,以确保您使用的是更新,更好的系统。

现在,super。不使用Parent.get(name),而是使用super电话:

p = super(Child, cls).get(name)

p将具有正确的类型,因为父方法中的cls与子方法中的cls相同。 (请注意,如果您以后添加了Grandchild类,则此行将生成Grandchild个对象而不是Child个对象。这很可能是正确的行为。)