前言
在面向对象编程中,类常有继承关系,子类需要复用或扩展基类逻辑。python 提供内置函数 super(),返回一个代理对象,用于按 mro(方法解析顺序) 调用当前类之后的下一个类的方法。这样可以避免硬编码父类名,使代码在多继承下更健壮、可维护。
一、函数语法
super([type[, object-or-type]])
参数:
- type:可选。通常为当前类。
- object-or-type:可选。当前实例(self)或当前类(配合类方法/静态方法显式传入)。
常见写法:
🔹实例方法
super().method(...) # 等价于: super(currentclass, self).method(...)
🔹类方法
@classmethod
def m(cls, ...):
super().method(...)
# 等价于:
super(currentclass, cls).method(...)返回值:
一个 super 代理对象,可用于调用 mro 中“当前类之后的下一个类” 的方法。
提示:
python 3 支持零参 super()。单参形式很少需要,一般用零参或两参。
二、基础用法示例
1、基本继承调用
class parent:
def greet(self):
print("hello from parent")
class child(parent):
def greet(self):
super().greet() # 调用父类方法
print("hello from child")
c = child()
c.greet()
# hello from parent
# hello from child2、构造函数链
class a:
def __init__(self):
print("a init")
class b(a):
def __init__(self):
super().__init__() # 调用 a.__init__()
print("b init")
b = b()
# a init
# b init三、进阶技巧
1、多继承与 mro(方法解析顺序)
class a:
def greet(self):
print("a")
class b(a):
def greet(self):
super().greet()
print("b")
class c(a):
def greet(self):
super().greet()
print("c")
class d(b, c):
def greet(self):
super().greet()
print("d")
d = d()
d.greet()
# a
# c
# b
# dmro 顺序:d → b → c → a → object。
super() 并非“父类调用”,而是沿 mro 从当前类的后继继续向上。
2、显式两参 super()
当你不在方法定义的典型上下文(或需要手动指明上下文)时,可显式传入两参:
class base:
def who(self): print("base.who")
class sub(base):
def who(self):
print("sub.who → call super:")
return super(sub, self).who()
sub().who()
# sub.who → call super:
# base.who3、类方法与静态方法
类方法可直接零参 super()(因为有 cls):
class a:
@classmethod
def hello(cls):
print("a hello")
class b(a):
@classmethod
def hello(cls):
super().hello()
print("b hello")
b.hello()
# a hello
# b hello静态方法中没有隐式的 self/cls,零参 super() 不可用。但可以显式两参使用(调用无需实例的方法):
class a:
@classmethod
def ping(cls): print("a.ping")
class b(a):
@staticmethod
def call_ping():
# 显式指定当前类与类型参数
super(b, b).ping()
b.call_ping()
# a.ping若要在静态方法中调用需要实例的方法,你必须自备实例并作为第二参传入(或改为实例/类方法设计)。
四、补充说明与常见误区
1、误把 super() 当“父类调用”
它依赖 mro,是当前位置之后的下一个类;多继承下若某类不调用 super(),调用链会被中断。
2、静态方法并非完全不能 super()
不能用零参,但可以显式两参(见上例)。关键是你是否有合适的第二参数以及要调用的是否为可在该上下文调用的方法(如 @classmethod)。
3、签名与参数传递
在 __init__ 或其他需要链式调用的方法中,建议:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
以免在多继承组合时出现参数不匹配。
小结
super() 返回一个基于 mro 的代理,不是“直接父类”的别名。
零参 super() 适用于实例方法与类方法;在静态方法或特殊上下文中,可用显式两参。
在多继承中配合合作式 super() 与一致的参数传递,能保证方法/构造链完整运行,避免菱形继承中的重复与遗漏。
到此这篇关于python中内置函数super()用法的文章就介绍到这了,更多相关python内置函数super()内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论