Python继承中调用父类__init__方法时为何无需传入self参数?
嘿,这个问题问得特别到位,好多刚上手Python继承的小伙伴都会在这儿犯迷糊~我来给你掰扯清楚:
首先你得明白super()到底是干啥的——它返回的是一个代理对象,这个对象已经自动帮你把当前子类的实例(也就是你写的self)和父类关联起来了。当你通过这个代理对象调用父类的__init__方法时,它会自动把self作为第一个参数传给父类的方法,根本不需要你手动写进去。
拿你的代码举例子:父类Person的__init__方法定义是def __init__(self, name, age):,这里的self是Python在调用方法时自动传入的实例。当你在子类Student里用super().__init__(name, age)时,super()已经悄悄把当前的Student实例(也就是self)传给了父类的__init__,所以父类方法拿到的参数正好是self, name, age,完美匹配。
那如果硬要写成super().__init__(self, name, age)会咋样?这就相当于你多传了一个参数!父类的__init__只需要除了self之外的两个参数,结果你给了三个(self, name, age),Python就会直接抛出参数不匹配的错误,比如TypeError: __init__() takes 3 positional arguments but 4 were given——因为Python本来还要自动传一个self,加上你手动传的,就变成4个了,肯定不对嘛。
另外补充个小知识点:Python 3的super()已经做了简化,不像Python 2那样必须写super(Student, self).__init__(name, age),它能自动从当前上下文里获取子类和实例信息,所以用起来更省心。
总结一下核心原因:
super()返回的代理对象会自动绑定当前实例,调用父类方法时无需手动传self- 手动传
self会导致参数数量超出父类方法的要求,触发错误 - Python 3的
super()语法已经简化,不用再显式指定类和实例
备注:内容来源于stack exchange,提问作者Song

