Python继承异常:子类重写方法未触发,仍执行父类方法
第一个关键错误:super() 参数用错了
你在重写父类方法时,super(Parent, self).method(param) 这行代码写错了——super() 的第一个参数应该是当前子类(也就是 Override),而不是父类 Parent。
为什么这会导致问题?当你传入 Parent 作为第一个参数时,Python 会从 Parent 的上一级父类开始查找方法(而不是从 Parent 本身),这直接跳过了你自己写的修复逻辑,相当于你的重写代码根本没生效。外部调用时自然还是走了父类的原始方法,bug 也就继续存在。
对应到你的实际场景里,ExtendedConfigParser 的 read_string 方法肯定也犯了同样的错误,导致你写的字符串修复逻辑没被执行,直接调用了父类 ConfigParser 的 read_string,才会抛出字符串类型错误。
第二个坑:Python2 的字符串类型差异
你用的是 Python2,这里的报错 TypeError: initial_value must be unicode or None, not str 是因为 Python2 里 str 是字节串,而父类 ConfigParser 的 read_string 要求传入 unicode 类型的字符串。你的修复思路是对的(要转换参数类型),但因为 super 的错误,这段逻辑根本没跑起来。
具体修复步骤
1. 修正 super() 的调用
在你的 ExtendedConfigParser 类里,把 read_string 方法的 super 调用改成下面这样:
from configparser import ConfigParser class ExtendedConfigParser(ConfigParser): def read_string(self, string): # 先处理Python2的字符串类型问题:把str转成unicode if isinstance(string, str): # 用utf-8解码,如果你配置文件是其他编码就改成对应编码 string = string.decode('utf-8') # 正确调用父类方法:第一个参数是当前子类,第二个是self super(ExtendedConfigParser, self).read_string(string)
2. 验证测试用例
修改后,你的测试代码里的 config_parser.read_string(content) 就会先执行你重写的逻辑,把从文件读取到的 str 类型的 content 转换成 unicode,再传给父类的方法,类型错误就会消失。
额外提醒(Python2 继承注意点)
- 在 Python2 中,
super()必须显式传入子类和self参数,这和 Python3 里直接写super()不一样。 - 确保你的子类继承的是新式类(比如
ConfigParser已经是新式类了,所以没问题)。
回到你的简化代码示例
把简化代码里的 super 修正后,就能正常生效:
class Parent(): def method(self, param): # 存在bug的代码 do_stuff() class Override(Parent): def method(self, param): # 已修复(测试有效) param = fix_param(param) # 修正:super的第一个参数是当前子类Override super(Override, self).method(param) class External(): def processing(): param = get_param() obj = Override() obj.method(param) # 现在会正确执行Override的修复逻辑
这样,当 External.processing() 调用 obj.method(param) 时,就会先执行你写的修复代码,再调用父类方法,bug 就能被修复了。
内容的提问来源于stack exchange,提问作者Hawker65

