Python super 函数
上次修改时间:2025 年 4 月 11 日
本综合指南探讨了 Python 的 super
函数,它可以在继承层次结构中实现对父类的方法调用。我们将涵盖基本用法、方法解析顺序和实际示例。
基本定义
super
函数返回一个代理对象,该对象将方法调用委托给父类或兄弟类。这对于 Python 中的协作多重继承至关重要。
主要特征:遵循方法解析顺序 (MRO),适用于单继承和多重继承,并有助于避免硬编码父类名称。
基本继承用法
这是一个简单的用法示例,展示了 super
如何在单继承场景中调用父类方法。
class Parent: def __init__(self): print("Parent __init__") def method(self): print("Parent method") class Child(Parent): def __init__(self): super().__init__() print("Child __init__") def method(self): super().method() print("Child method") c = Child() c.method()
此示例演示了基本的 super
用法。Child 类调用 Parent 的方法,而无需显式命名 Parent,从而使代码更易于维护。
输出显示父方法和子方法都执行,由于 super
委托,父方法首先被调用。
多重继承
super
在多重继承中变得特别强大。此示例显示了菱形模式继承和方法解析。
class A: def method(self): print("A method") super().method() class B: def method(self): print("B method") class C(A, B): def method(self): print("C method") super().method() c = C() c.method() print(C.__mro__) # Show method resolution order
这演示了 super
如何遵循 MRO (C → A → B)。即使 A 不继承自 B,每个类的方法都会调用链中的下一个类。
MRO 输出显示了 Python 用于解析方法调用的线性化继承路径。
super 与类方法
super
也适用于类方法。此示例显示了在 classmethod 上下文中的正确用法。
class Base: @classmethod def create(cls): print(f"Base.create({cls})") return cls() class Derived(Base): @classmethod def create(cls): print(f"Derived.create({cls})") instance = super().create() print(f"Created {instance}") return instance d = Derived.create()
该示例显示了 classmethod 中的 super
正确地将派生类 (cls) 传递给父类的 classmethod。这保持了适当的多态性。
输出演示了调用链,并显示了通过继承层次结构的实例创建过程。
super 在属性覆盖中
此示例演示了如何使用 super
来扩展属性行为,而无需完全覆盖它。
class Person: def __init__(self, name): self._name = name @property def name(self): return self._name @name.setter def name(self, value): self._name = value class Employee(Person): @property def name(self): return super().name.upper() @name.setter def name(self, value): super(Employee, Employee).name.__set__(self, value) e = Employee("John") print(e.name) # JOHN e.name = "Alice" print(e.name) # ALICE
Employee 类扩展了 name 属性 getter,同时保留了父类的 setter 行为。请注意属性 setter 所需的特殊语法。
当您希望修改属性行为,同时保留底层存储机制时,此模式非常有用。
super 与 __init_subclass__
Python 3.6+ 引入了 __init_subclass__
。此示例显示了 super
如何使用此特殊类方法。
class PluginBase: plugins = [] def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls.plugins.append(cls) print(f"Registered plugin {cls.__name__}") class PluginA(PluginBase): pass class PluginB(PluginBase): pass print(PluginBase.plugins) # [<class '__main__.PluginA'>, <class '__main__.PluginB'>]
该示例演示了一个插件注册系统。每个子类都调用 super().__init_subclass__
以确保正确的初始化链接。
此模式在需要跟踪基类的所有子类的框架中很常见。
最佳实践
- 始终一致使用: 始终使用 super() 而不是直接父类调用
- 理解 MRO: 了解类层次结构的方法解析顺序
- 传递参数: 确保层次结构中的所有方法接受相同的参数
- 记录覆盖: 清楚地记录方法何时扩展父类行为
- 彻底测试: 多重继承需要仔细测试
资料来源
作者
列出所有 Python 教程。