Python方法的重载和方法的覆盖
前言先把一个前提讲清楚这个标题把重载和覆盖并列容易让人以为 Python 同时支持两者。实际上 Python 只支持方法覆盖overriding不支持传统意义上的方法重载overloading。方法覆盖子类定义与父类同名的方法运行时调用的是子类的版本。这个 Python 完全支持。方法重载在同一个作用域里用同一个名字、不同的参数列表定义多个函数/方法由编译器或运行环境根据实参个数或类型自动选择。Java、C 支持它Python 不支持——在 Python 里同一个名字第二次定义会把第一次的直接覆盖掉前一个定义连影子都不剩。需要区分的是Python 虽然有typing.overload这个名字相似的装饰器但它只服务于静态类型检查器运行时不做任何分派——文档明确写着被overload装饰的定义会被后面那个不带overload的定义覆盖运行时直接调overload装饰的函数会抛NotImplementedError。所以本文讲三件事覆盖怎么写为什么重载在 Python 里行不通以及当真的需要按参数个数或类型分派时用什么方式替代。一、方法覆盖Python 支持的写法覆盖就是子类重写父类方法。它依赖属性查找先实例、再沿 MRO 找类子类在 MRO 里排在父类前面所以子类版本被选中。# 适用于 Python 3.8class Base:def greet(self):return baseclass Child(Base):def greet(self): # 与父类同名 → 覆盖return childprint(Child().greet()) # child要在覆盖的同时保留父类的行为用super()调一下# 适用于 Python 3.8class Base:def greet(self):return baseclass Child(Base):def greet(self):return super().greet() childprint(Child().greet()) # basechild注意覆盖时保持调用签名兼容。子类如果偷偷改掉了参数个数多态调用点就会在某处突然抛TypeError。二、为什么重载在 Python 里行不通看下面这段看起来像重载的代码# 适用于 Python 3.8class Calculator:def add(self, a, b):return a bdef add(self, a, b, c): # 这个名字把上面那个覆盖掉了return a b ccalc Calculator()print(calc.add(1, 2, 3)) # 6# calc.add(1, 2) # TypeError: add() missing 1 required positional argument类体也是一个作用域两个def add同名后一个直接覆盖前一个。所以calc.add(1, 2)会失败——不是没匹配到两个参数的重载版本而是那个版本根本不存在。这背后的原因是Python 是动态类型语言函数对象只认名字不像静态编译语言那样在编译期根据签名生成多份符号。变量名在模块/类命名空间里就是唯一的键。因此Python 里想说支持多种调用形式只能靠一个函数体内部判断或者靠运行时的类型分派。三、替代方案一默认参数与可变参数如果不同重载版本的差异只在于参数个数用默认参数default argument或可变参数*args/**kwargs就够了。# 适用于 Python 3.8class Calculator:def add(self, a, b, c0):return a b ccalc Calculator()print(calc.add(1, 2)) # 3print(calc.add(1, 2, 3)) # 6如果差异在于类型朴素做法是在函数体里分支但那正是多态想消灭的写法# 适用于 Python 3.8def render(value):if isinstance(value, str):return str: valueif isinstance(value, int):return fint:{value}return str(value)这种写法勉强可用但每当新增类型就要回来改这个函数违反了开闭原则。四、替代方案二单分派singledispatch标准库functools提供了单分派泛型函数single-dispatch generic function把函数变成按第一个参数的类型选择实现的入口。# 适用于 Python 3.8from functools import singledispatchsingledispatchdef describe(value):return funknown:{value}describe.registerdef _(value: int):return fint:{value}describe.registerdef _(value: str):return fstr:{value}print(describe(10)) # int:10print(describe(hi)) # str:hiprint(describe(1.5)) # unknown:1.5要点singledispatch从 Python 3.4 起提供只按第一个参数的类型分派用describe.register配上类型注解来注册实现被singledispatch装饰的那个原函数注册在object上作为兜底。用于类方法时用functools.singledispatchmethod需要Python 3.8 及以上。此时分派依据是第一个非self/ 非cls的参数# 适用于 Python 3.8from functools import singledispatchmethodclass Formatter:singledispatchmethoddef format(self, value):return str(value)format.registerdef _(self, value: int):return fint:{value}format.registerdef _(self, value: str):return fstr:{value}f Formatter()print(f.format(3)) # int:3print(f.format(a)) # str:aprint(f.format(1.5)) # 1.5文档特别提醒singledispatchmethod 要和别的装饰器如classmethod叠加时必须放在最外层否则register拿不到正确的绑定。分派是沿类型的 MRO 找最近的注册实现也会考虑注册在抽象基类上的实现——所以bool是int的子类format(True)会走到int的实现输出int:True。下表对比三个容易混淆的概念概念运行时是否可依据参数个数/类型选择Python 支持情况方法覆盖 overriding否只看 MRO 选同名方法支持传统方法重载 overloading是不支持同名后者覆盖前者typing.overload否仅供类型检查器提供但运行时不分派singledispatch按第一个参数类型3.4 提供singledispatchmethod按第一个非 self 参数类型3.8 提供常见坑点1. 以为同名不同参数的方法算重载❌# 适用于 Python 3.8class C:def f(self, a): ...def f(self, a, b): ...✅ 只有第二个存在要支持两种调用写成def f(self, a, bNone):。2. 用typing.overload指望运行时按类型选❌ 以为加了overload就能运行时分派——它只是给类型检查器的声明运行时会抛NotImplementedError。✅ 运行时按类型分派用functools.singledispatch/singledispatchmethod。3.singledispatchmethod没放在最外层❌# 适用于 Python 3.8class C:classmethodsingledispatchmethoddef f(cls, x): ...✅ 让singledispatchmethod处于最外层register才能正确工作。4. 指望singledispatch按多个参数分派❌ 以为它能像多重分派multiple dispatch那样同时看两个参数。✅ 它只看第一个方法里是第一个非self参数的类型。5. 覆盖父类方法时改了签名❌ 父类def save(self, path)子类写成def save(self)多态调用点传入参数就TypeError。✅ 覆盖方法保持兼容签名新增能力用带默认值的参数。6. 覆盖后忘记保留父类行为❌ 子类重写__init__却不调super().__init__()父类设置的属性全丢。✅ 需要父类逻辑时用super().方法名(...)显式调用。7. 在函数体里堆isinstance分支冒充重载❌ 每加一种类型都要回来改函数还容易漏掉子类。✅ 简单场景用singledispatch面向对象的场景用方法覆盖。8. 注册实现时忘了类型注解❌describe.register下面的函数没写value: int注册不进int永远走兜底实现。✅ 注册函数必须带类型注解注解即分派依据。总结需求推荐做法子类改变父类行为方法覆盖必要时super()保留父类逻辑参数个数不同默认参数、*args/**kwargs按参数类型分派函数functools.singledispatch3.4按参数类型分派方法functools.singledispatchmethod3.8只想让类型检查器知道多种签名typing.overload运行时无效记住一句话就能避开绝大多数困惑Python 有覆盖没有传统重载。同名方法会互相覆盖需要多种形态时要么把差异交给继承与多态要么用singledispatch系列做运行时类型分派typing.overload则是纯给静态检查器看的另一回事。

相关新闻

草莓目标检测数据集YOLO/VOC格式转换与训练避坑实战

草莓目标检测数据集YOLO/VOC格式转换与训练避坑实战

简介:面向农业与计算机视觉开发者,这份草莓目标检测数据集覆盖VOC和YOLO两种主流标注格式,可直接用于目标检测模型训练与算法验证。VOC部分按JPEGImages图片目录和Annotations标签目录组织,每张jpg带对应xml框选信息;Y…

2026/10/11 10:59:29 阅读更多 →
糖尿病足溃疡风险评分:基于深度学习的CNN模型与PyTorch实现

糖尿病足溃疡风险评分:基于深度学习的CNN模型与PyTorch实现

简介:这是一份基于深度学习构建的糖尿病足溃疡(DFU)风险评分系统完整代码包,面向医学图像分析、AI辅助诊断方向的开发者与研究者,也适合作为深度学习的课程设计或毕业设计参考。压缩包共54个文件,以24个Pyt…

2026/10/11 10:59:29 阅读更多 →
IOP一致性测试框架:从协议描述到持续集成的工程化实践

IOP一致性测试框架:从协议描述到持续集成的工程化实践

1. 项目缘起与整体设计思路1.1 为什么需要一致性测试做过存储、分布式系统或中间件开发的朋友,大概率都遇到过这种场景:单机跑得好好的服务,一上集群就出问题;某个接口在本地测试全绿,到了联调环境就间歇性超时&#x…

2026/10/11 10:59:29 阅读更多 →

最新新闻

Browserify与Webpack时代已来,为什么还要回顾Ender?ded、fat、rvagg的开放模块运动编年史

Browserify与Webpack时代已来,为什么还要回顾Ender?ded、fat、rvagg的开放模块运动编年史

开发工具 【免费下载链接】Ender the no-library library: open module JavaScript framework 项目地址: https://gitcode.com/gh_mirrors/en/Ender 点击查看 免费下载 Ender 是浏览器时代的“npm 小妹妹”——一个专为前端 JavaScript 包而生的浏览器包管理器&…

2026/10/11 11:54:18 阅读更多 →
Gatsby 中使用 TypeScript 构建站点的完整实践:基于 using-typescript 示例站点

Gatsby 中使用 TypeScript 构建站点的完整实践:基于 using-typescript 示例站点

前端静态站点Web框架 【免费下载链接】gatsby React-based framework with performance, scalability, and security built in. 项目地址: https://gitcode.com/gh_mirrors/ga/gatsby 点击查看 免费下载 本篇指南以 Gatsby 官方仓库中的 using-typescript 示例站点…

2026/10/11 11:54:18 阅读更多 →
PyTorch卷积神经网络实战:环境搭建、训练调参与ONNX导出

PyTorch卷积神经网络实战:环境搭建、训练调参与ONNX导出

简介:这份资源面向深度学习入门者与计算机视觉方向的初学者,围绕PyTorch框架下卷积神经网络的实现展开,帮助读者理解CNN的基本结构与训练流程。包内共10个文件,以4个py脚本和2个pt模型文件为主,另含MNIST数据集的图像与…

2026/10/11 11:54:18 阅读更多 →
MBA论文降AI率实战指南:9个工具与五步改写流程

MBA论文降AI率实战指南:9个工具与五步改写流程

这半年,我带过不少MBA方向的学生改课程论文和商业案例分析报告,几乎每隔几天就会有人拿着检测报告问我同一个问题:AI率又到百分之六七十了,到底怎么降下来?市面上的“降AI率工具”五花八门,名字一个比一个玄…

2026/10/11 11:54:18 阅读更多 →
基于SpringBoot+Vue的企业知识产权管理系统设计与实现

基于SpringBoot+Vue的企业知识产权管理系统设计与实现

作为一名挨过了毕业设计洗礼、后来也带过不少本科生做项目的过来人,每次看到“基于SpringBootVue”这种组合的题目,第一反应就是:选对方向了,但能不能做出彩,还得看怎么落地。今天要聊的这个“企业内部知识产权管理系统…

2026/10/11 11:54:18 阅读更多 →
调试工具与技巧全解析:从日志到链路追踪的实战指南

调试工具与技巧全解析:从日志到链路追踪的实战指南

1. 调试工具与技巧的底层逻辑重构1.1 为什么调试能力是区分开发者水平的分水岭干了这么多年技术,我越来越觉得,写代码这件事本身其实没那么难,真正拉开差距的是调试能力。同样一个Bug,有人十分钟定位到根因,有人折腾两…

2026/10/11 11:53:18 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →