Python中super()括号传参与__init__括号传参的区别及适用场景
好问题!这其实是Python版本差异和super语法糖带来的两种写法,咱们拆开说清楚:
两种
super传参方式的核心区别 首先得明确:super()括号里的参数是给super本身用的,而__init__()括号里的参数是传给父类构造函数的,这是完全不同的两个东西。
1. 显式传参:super(Maze, self).__init__()
这是Python 2时代的标准写法,在Python 3里也能运行,但已经没必要用了。它的作用是:
- 告诉
super:“基于self这个实例的方法解析顺序(MRO),找到Maze类的下一个父类,然后调用它的__init__方法” - 在你的例子里,
Maze继承了tk.Tk和object,所以MRO里Maze的下一个类是tk.Tk,这行代码本质就是调用tk.Tk.__init__(self)
这种写法的缺点很明显:如果哪天你把类名从Maze改成了GameMaze,你还得手动修改super里的类名,不然就会出错。
2. 隐式传参:super().__init__(参数)
这是Python 3引入的语法糖,它会自动从当前上下文里获取两个关键信息:
- 当前定义
super()的类(也就是你写super()时所在的那个类) - 当前实例
self
所以它等价于super(当前类名, self).__init__(参数),但不用你手动写类名,代码更简洁也更易维护。
比如如果你的代码改成:
class Maze(tk.Tk): def __init__(self, width, height): super().__init__() # 等价于super(Maze, self).__init__() self.width = width self.height = height
这里super().__init__()自动找到tk.Tk的构造函数并调用,要是之后你改了类名,这行代码完全不用动。
如果需要给父类构造函数传参数,直接放在__init__()的括号里就行,比如tk.Tk的构造函数支持传入窗口标题,你可以写成:
super().__init__(title="迷宫游戏")
该选哪种写法?
- 如果你只需要兼容Python 3及以上版本:优先用
super().__init__(...),简洁、不容易出错,维护成本低。 - 如果你的代码必须兼容Python 2:那只能用显式传参的
super(类名, self).__init__(),因为Python 2不支持无参的super()。 - 极少数场景下,你需要手动指定要调用的父类(比如多继承中想跳过某个父类的方法),才会用到显式传参,但这种情况非常少见,一般不推荐这么做,因为会破坏MRO的逻辑。
最后再强调一遍:别搞混super()的参数和__init__()的参数——前者是告诉super“找谁”,后者是告诉父类构造函数“要初始化什么”。
内容的提问来源于stack exchange,提问作者Himansu Odedra
相关产品推荐
相关产品推荐

