
在Python继承中,super().__init__(...)无需手动传入self,因为super()返回的代理对象已自动绑定实例,调用时self作为隐式第一个参数被传递——这与普通实例方法调用机制完全一致。
在python继承中,`super().__init__(...)`无需手动传入`self`,因为`super()`返回的代理对象已自动绑定实例,调用时`self`作为隐式第一个参数被传递——这与普通实例方法调用机制完全一致。
理解这一设计的关键在于:super()不是普通函数,而是一个动态代理对象;super().__init__()本质上是绑定方法(bound method)的调用,而非未绑定的函数调用。
当执行 super().__init__(name, age) 时,Python 实际上做了以下两件事:
- 通过
super()查找父类Person中的__init__方法; - 将当前
Student实例(即self)自动绑定到该方法上,形成一个已绑定的调用上下文; - 因此,你只需传入
name和age——self已由运行时隐式提供。
这与你调用 self.get_name() 的原理完全相同:
class Student(Person):
def introduce(self):
self.get_name() # ✅ 正确:self 隐式传入
# self.get_name(self) # ❌ 错误:重复传入 self,会报 TypeError: get_name() takes 1 positional argument but 2 were given
同样地,若错误地写成:
def __init__(self, name, age, GPA):
super().__init__(self, name, age) # ❌ TypeError!
self.GPA = GPA
Python 会抛出类似错误:TypeError: __init__() takes 3 positional arguments but 4 were given
(因为 Person.__init__ 定义为 def __init__(self, name, age) → 接收 3 个参数,而 super().__init__(self, name, age) 实际传入了 4 个:隐式 self + 显式 self, name, age)
✅ 正确写法始终是:
def __init__(self, name, age, GPA):
super().__init__(name, age) # self 由 super() 自动注入
self.GPA = GPA
? 补充说明:super() 返回的对象实现了描述符协议(Descriptor Protocol),其 __get__ 方法会在属性访问时自动将调用者实例(self)绑定为第一个参数。这也是 Python 方法“自动绑定”的底层机制(详见 Python Descriptor How-To)。
总结:不要向 super().__init__() 显式传 self,不是约定俗成,而是语言机制强制要求——它和所有实例方法一样,self 是隐式、不可省略且不可重复的首参。掌握这一点,能帮你更扎实地理解 Python 的面向对象模型与方法调用本质。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











