Python子类重写classmethod后返回正确类实例的实现方法
问题原因
你当前的代码里,Bar.read调用cls.__base__.read(fname0)时,相当于直接调用了Foo.read(fname0),此时Foo.read方法里的cls参数是Foo类,所以最终返回的是Foo的实例,而非Bar。
解决方案
只需要把Bar.read里调用父类方法的方式换成super()即可,修改后的完整代码如下:
class Foo: def __init__(self, pars): self.pars = pars @classmethod def read(cls, fname): pars = some_method_to_read_the_file(fname) return cls(pars) class Bar(Foo): @classmethod def read(cls, fname): fname0 = somehow_prepare_filename(fname) return super().read(fname0)
原理说明
super()会返回一个绑定了当前子类上下文的父类代理对象,调用它的read方法时,会自动把当前的cls(也就是Bar类)作为参数传递给父类的read方法。这样父类read里的cls就变成了Bar,最终实例化并返回的就是Bar对象。
如果不想用super(),也可以手动传递当前cls给父类的read方法,写法如下:
return Foo.read(cls, fname0)
不过super()更适配继承场景,尤其是多继承时能避免硬编码父类名称,代码更健壮。
内容的提问来源于stack exchange,提问作者olebole
相关产品推荐
相关产品推荐

