在Python中实现函数重载的示例代码


Posted in Python onDecember 12, 2019

假设你有一个函数connect,它有一个参数address,这个参数可能是一个字符串,也可能是一个元组。例如:

connect('123.45.32.18:8080')
connect(('123.45.32.18', 8080))

你想在代码里面兼容这两种写法,于是你可能会这样写代码:

def connect(address):
 if isinstance(address, str):
 ip, port = address.split(':')
 elif isinstance(address, tuple):
 ip, port = address
 else:
 print('地址格式不正确')

这种写法简单直接,但是如果参数的类型更多,那么你就需要写很长的 if-elif-elif-...-else 。代码看起来就非常不美观。

学习过 Java 的同学,应该对函数重载比较熟悉,可以定义几个名字相同的函数,但是他们的参数类型或者数量不同,从而实现不同的代码逻辑。

在 Python 里面,参数的数量不同可以使用默认参数来解决,不需要定义多个函数。那如果参数类型不同就实现不同的逻辑,除了上面的 if-else 外,我们还可以使用 functools 模块里面的 singledispatch 装饰器实现函数重载。

我们来写一段代码:

from functools import singledispatch

@singledispatch
def connect(address):
 print(f' 传输参数类型为:{type(address)},不是有效类型')

@connect.register
def _(address: str):
 ip, port = address.split(':')
 print(f'参数为字符串,IP是:{ip}, 端口是:{port}')

@connect.register
def _(address: tuple):
 ip, port = address
 print(f'参数为元组,IP是:{ip}, 端口是:{port}')

connect('123.45.32.18:8080')
connect(('123.45.32.18', 8080))
connect(123)

我们运行一下这段代码,大家看看根据参数的不同,有什么样的不同效果:

在Python中实现函数重载的示例代码

可以看到,我们调用的函数,始终都是 connect ,但是由于传入参数的类型不同,它运行的结果也不一样。

我们使用 singledispatch 装饰一个函数,那么这个函数就是我们将会调用的函数。

这个函数在传入参数不同时的具体实现,通过下面注册的函数来实现。注册的时候使用 @我们定义的函数名.register 来注册。被注册的函数名叫什么无关紧要,所以这里我都直接使用下划线代替。

被注册的函数的第一个参数,通过类型标注来确定它应该使用什么类型。当我们调用我们定义的函数是,如果参数类型符合某个被注册的函数,那么就会执行这个被注册的函数。如果参数类型不满足任何一个被注册的函数,那么就会执行我们的原函数。

使用类型标注来指定参数类型是从 Python 3.7才引入的新特性。在 Python 3.6或之前的版本,我们需要通过 @我们定义的函数名.register(类型) 来指定类型,例如:

from functools import singledispatch

@singledispatch
def connect(address):
 print(f' 传输参数类型为:{type(address)},不是有效类型')

@connect.register(str)
def _(address):
 ip, port = address.split(':')
 print(f'参数为字符串,IP是:{ip}, 端口是:{port}')

@connect.register(tuple)
def _(address):
 ip, port = address
 print(f'参数为元组,IP是:{ip}, 端口是:{port}')

同时,还有一个需要注意的点,就是只有第一个参数的不同类型会被重载。后面的参数的类型变化会被自动忽略。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python备份Mysql脚本
Aug 11 Python
对于Python装饰器使用的一些建议
Jun 03 Python
Python编程中的异常处理教程
Aug 21 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
Jan 05 Python
微信跳一跳游戏python脚本
Apr 01 Python
python爬虫爬取某站上海租房图片
Feb 04 Python
python3.5安装python3-tk详解
Apr 26 Python
利用python计算windows全盘文件md5值的脚本
Jul 27 Python
Python3 文章标题关键字提取的例子
Aug 26 Python
python已协程方式处理任务实现过程
Dec 27 Python
python小白切忌乱用表达式
May 29 Python
python3.4中清屏的处理方法
Jul 06 Python
django框架F&Q 聚合与分组操作示例
Dec 12 #Python
使用OpenCV-python3实现滑动条更新图像的Canny边缘检测功能
Dec 12 #Python
django框架使用views.py的函数对表进行增删改查内容操作详解【models.py中表的创建、views.py中函数的使用,基于对象的跨表查询】
Dec 12 #Python
python3中pip3安装出错,找不到SSL的解决方式
Dec 12 #Python
python 使用opencv 把视频分割成图片示例
Dec 12 #Python
Python2与Python3的区别点整理
Dec 12 #Python
opencv3/C++实现视频背景去除建模(BSM)
Dec 11 #Python
You might like
php实现以只读方式打开文件的方法
2015/03/16 PHP
一个不错的用JavaScript实现的UBB编码函数
2007/03/09 Javascript
javascript常用方法、属性集合及NodeList 和 HTMLCollection 的浏览器差异
2010/12/25 Javascript
Fixie.js 自动填充内容的插件
2012/06/28 Javascript
js、jquery图片动画、动态切换示例代码
2014/06/03 Javascript
JS实现的另类手风琴效果网页内容切换代码
2015/09/08 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
jQuery中的siblings用法实例分析
2015/12/24 Javascript
Node.js实用代码段之正确拼接Buffer
2016/03/17 Javascript
vue实现某元素吸顶或固定位置显示(监听滚动事件)
2017/12/13 Javascript
解决VUE中document.body.scrollTop为0的问题
2018/09/15 Javascript
关于JS模块化的知识点分享
2019/10/16 Javascript
nodejs实现的http、https 请求封装操作示例
2020/02/06 NodeJs
openlayers4实现点动态扩散
2020/08/17 Javascript
基于vue项目设置resolves.alias: '@'路径并适配webstorm
2020/12/02 Vue.js
解析Python中的生成器及其与迭代器的差异
2016/06/20 Python
windows10系统中安装python3.x+scrapy教程
2016/11/08 Python
神经网络python源码分享
2017/12/15 Python
安装python时MySQLdb报错的问题描述及解决方法
2018/03/20 Python
python增加图像对比度的方法
2019/07/12 Python
python如何支持并发方法详解
2020/07/25 Python
python字典通过值反查键的实现(简洁写法)
2020/09/30 Python
python安装及变量名介绍详解
2020/12/12 Python
详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
2021/01/29 Python
2分钟教你实现环形/扇形菜单(基础版)
2020/01/15 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
时尚圣经:The Fashion Bible
2019/03/03 全球购物
英国在线滑雪板和冲浪商店:The Board Basement
2020/01/11 全球购物
EJB发布WEB服务一般步骤
2012/10/31 面试题
大学生毕业自我鉴定范文
2013/09/19 职场文书
烹调加工管理制度
2014/02/04 职场文书
工厂车间标语
2014/06/19 职场文书
2015年信贷员工作总结
2015/04/28 职场文书
高中16字霸气押韵班级口号集锦!
2019/06/27 职场文书
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js
《进击的巨人》新联动CM 兵长强势出击兽巨人
2022/04/05 日漫