在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实现正则检测密码合法性
Jan 05 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
Jul 02 Python
Python解惑之True和False详解
Apr 24 Python
Python3 操作符重载方法示例
Nov 23 Python
Flask-Mail用法实例分析
Jul 21 Python
如何实现更换Jupyter Notebook内核Python版本
May 18 Python
Python flask框架实现浏览器点击自定义跳转页面
Jun 04 Python
Python中如何添加自定义模块
Jun 09 Python
详解python实现可视化的MD5、sha256哈希加密小工具
Sep 14 Python
基于python爬取梨视频实现过程解析
Nov 09 Python
python 中的@运算符使用
May 26 Python
python中%格式表达式实例用法
Jun 18 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控制网页过期时间的代码
2008/09/28 PHP
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
php中实现用数组妩媚地生成要执行的sql语句
2015/07/10 PHP
PHP magento后台无法登录问题解决方法
2016/11/24 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
php微信公众号开发之简答题
2018/10/20 PHP
Laravel统计一段时间间隔的数据方法
2019/10/09 PHP
基于jQuery的模仿新浪微博时间的组件
2011/10/04 Javascript
简单理解JavaScript中的封装与继承特性
2016/03/19 Javascript
Javascript动画效果(2)
2016/10/11 Javascript
关于js函数解释(包括内嵌,对象等)
2016/11/20 Javascript
js实现淡入淡出轮播切换功能
2017/01/13 Javascript
jQuery插件版本冲突的处理方法分析
2017/01/16 Javascript
AngularJS报错$apply already in progress的解决方法分析
2017/01/30 Javascript
vue-resouce设置请求头的三种方法
2017/09/12 Javascript
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
详解基于mpvue的小程序markdown适配解决方案
2018/05/08 Javascript
JS实现盒子跟着鼠标移动及键盘方向键控制盒子移动效果示例
2019/01/29 Javascript
微信实现自动跳转到用其他浏览器打开指定APP下载
2019/02/15 Javascript
微信小程序 wx:for遍历循环使用实例解析
2019/09/09 Javascript
在python中用print()输出多个格式化参数的方法
2019/07/16 Python
python中if及if-else如何使用
2020/06/02 Python
python使用正则表达式匹配txt特定字符串(有换行)
2020/12/09 Python
Python实现石头剪刀布游戏
2021/01/20 Python
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
美国折扣网站:jClub
2017/08/07 全球购物
历史学专业个人的自我评价
2013/10/13 职场文书
优良学风班总结材料
2014/02/08 职场文书
信用社主任竞聘演讲稿
2014/05/23 职场文书
计算机网络专业求职信
2014/06/05 职场文书
化工专业自荐书
2014/06/16 职场文书
师德先进个人事迹材料
2014/12/19 职场文书
同意落户证明
2015/06/19 职场文书
2016企业先进集体事迹材料
2016/02/25 职场文书
导游词之山海关
2019/12/10 职场文书
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL