理解Python中super()与__init__()方法的使用

理解Python中super()与__init__()方法的使用

技术背景

在Python中,super() 函数是一个非常有用的工具,它允许子类调用父类的方法,避免显式地引用父类名称。特别是在多重继承的场景中,super() 能确保在方法解析顺序(MRO)中正确调用下一个父类的函数。

实现步骤

Python 3 中使用 super()

在 Python 3 中,调用 super() 变得更加简洁,可以直接使用 super().__init__() 调用父类的 __init__ 方法:

1
2
3
4
5
6
7
8
class Base:
def __init__(self):
print("Base init'ed")

class ChildB(Base):
def __init__(self):
print("ChildB init'ed")
super().__init__()

Python 2 中使用 super()

在 Python 2 中,需要显式地指定子类和实例对象:

1
2
3
4
5
6
7
8
class Base(object):
def __init__(self):
print("Base init'ed")

class ChildB(Base):
def __init__(self):
print("ChildB init'ed")
super(ChildB, self).__init__()

不使用 super()

如果不使用 super(),则需要显式地调用父类的方法:

1
2
3
4
5
6
7
8
class Base:
def __init__(self):
print("Base init'ed")

class ChildA(Base):
def __init__(self):
print("ChildA init'ed")
Base.__init__(self)

核心代码

模拟 super() 的实现

以下是一个简化的 super() 实现:

1
2
3
4
5
6
7
class ChildB(Base):
def __init__(self):
mro = type(self).mro()
for next_class in mro[mro.index(ChildB) + 1:]:
if hasattr(next_class, '__init__'):
next_class.__init__(self)
break

多重继承示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Base(object):
def __init__(self):
print("Base init'ed")

class ChildA(Base):
def __init__(self):
print("ChildA init'ed")
Base.__init__(self)

class ChildB(Base):
def __init__(self):
print("ChildB init'ed")
super().__init__()

class UserDependency(Base):
def __init__(self):
print("UserDependency init'ed")
super().__init__()

class UserA(ChildA, UserDependency):
def __init__(self):
print("UserA init'ed")
super().__init__()

class UserB(ChildB, UserDependency):
def __init__(self):
print("UserB init'ed")
super().__init__()

最佳实践

  • 使用 Python 3:Python 3 中的 super() 语法更加简洁,建议使用 Python 3 进行开发。
  • 设计可协作的类:在多重继承场景中,使用 super() 确保类之间的协作性,避免硬编码父类调用。
  • 避免使用 self.__class__:在 super() 中使用 self.__class__ 会导致递归调用,应避免使用。

常见问题

使用 self.__class__ 导致递归错误

1
2
3
4
5
6
7
8
9
10
11
12
13
class Polygon(object):
def __init__(self, id):
self.id = id

class Rectangle(Polygon):
def __init__(self, id, width, height):
super(self.__class__, self).__init__(id)
self.shape = (width, height)

class Square(Rectangle):
pass

Square('a', 10, 10) # 会导致递归错误

静态方法无法使用 super()

由于静态方法没有访问类的 MRO,因此无法使用 super()

Python 2 中 super() 的限制

在 Python 2 中,只有当父类继承自 object(新风格类)时才能使用 super()


理解Python中super()与__init__()方法的使用
https://119291.xyz/posts/2025-05-09.understanding-python-super-with-init-methods/
作者
ww
发布于
2025年5月9日
许可协议