You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中父类__init__为何会调用子类重写的方法?

父类初始化调用方法时触发子类方法参数不匹配异常

最小可复现示例

class Parent:
    def __init__(self, arg):
        self.some_method(arg)  # 本意是调用Parent类的some_method
    
    def some_method(self, arg1):  # 为何父类__init__未调用此方法?
        print(f"Parent method called with arg1: {arg1}")


class Child(Parent):
    def __init__(self):
        Parent.__init__(self, "Hello")
        # 子类__init__无需调用some_method
    
    def some_method(self, arg1, arg2):  # 子类有两个参数,为何父类__init__调用了它?
        print(f"Child method called with arg1: {arg1} and arg2: {arg2}")
        super().some_method(arg1)


child = Child()  # 触发异常

预期结果

Parent method called with arg1: Hello

实际结果

TypeError: Child.some_method() missing 1 required positional argument: 'arg2'

原因解析

Python中方法调用是基于实例的实际类型实现动态绑定的:当在Parent.__init__里调用self.some_method(arg)时,self指向的是实际创建的Child实例,而非Parent实例。因此解释器会优先查找Child类中重写的some_method,而非父类的同名方法,这就是导致参数不匹配报错的核心原因。

解决方案(保持参数数量不同的前提下)

方法1:直接调用父类的方法

在父类__init__中,不通过self调用,而是直接用Parent.some_method(self, arg)的方式指定调用父类的方法,跳过动态绑定逻辑:

class Parent:
    def __init__(self, arg):
        Parent.some_method(self, arg)  # 直接调用父类方法
    
    def some_method(self, arg1):
        print(f"Parent method called with arg1: {arg1}")


class Child(Parent):
    def __init__(self):
        Parent.__init__(self, "Hello")
    
    def some_method(self, arg1, arg2):
        print(f"Child method called with arg1: {arg1} and arg2: {arg2}")
        super().some_method(arg1)


child = Child()  # 输出预期结果:Parent method called with arg1: Hello

方法2:子类方法设置参数默认值

给子类some_method的第二个参数设置默认值,使其兼容父类的调用方式,同时保留自身需要两个参数的能力:

class Parent:
    def __init__(self, arg):
        self.some_method(arg)
    
    def some_method(self, arg1):
        print(f"Parent method called with arg1: {arg1}")


class Child(Parent):
    def __init__(self):
        Parent.__init__(self, "Hello")
    
    def some_method(self, arg1, arg2=None):  # 添加默认值
        if arg2 is not None:
            print(f"Child method called with arg1: {arg1} and arg2: {arg2}")
        super().some_method(arg1)


child = Child()  # 输出预期结果:Parent method called with arg1: Hello
# 子类自身调用时仍可传两个参数
child.some_method("Hi", "World")  # 输出:Child method called with arg1: Hi and arg2: World / Parent method called with arg1: Hi

内容的提问来源于stack exchange,提问作者Ashark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 03:42:29