在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写xml文件的操作实例
Oct 05 Python
200 行python 代码实现 2048 游戏
Jan 12 Python
python测试mysql写入性能完整实例
Jan 18 Python
python使用Pycharm创建一个Django项目
Mar 05 Python
Python 实现异步调用函数的示例讲解
Oct 14 Python
基于Python在MacOS上安装robotframework-ride
Dec 28 Python
Python原始套接字编程实例解析
Jan 29 Python
python数据爬下来保存的位置
Feb 17 Python
Python中sys模块功能与用法实例详解
Feb 26 Python
Django import export实现数据库导入导出方式
Apr 03 Python
python实现手势识别的示例(入门)
Apr 15 Python
pytho matplotlib工具栏源码探析一之禁用工具栏、默认工具栏和工具栏管理器三种模式的差异
Feb 25 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脚本加密专家php解密算法
2020/09/13 PHP
用php实现选择排序的解决方法
2013/05/04 PHP
PHP连接局域网MYSQL数据库的简单实例
2013/08/26 PHP
php ci框架中加载css和js文件失败的解决方法
2014/03/03 PHP
PHP学习笔记之php文件操作
2016/06/03 PHP
PHP入门教程之会话控制技巧(cookie与session)
2016/09/11 PHP
PHP递归遍历指定文件夹内的文件实现方法
2016/11/15 PHP
js 加载时自动调整图片大小
2008/05/28 Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
2012/01/15 Javascript
基于JQuery实现的Select级联
2014/01/27 Javascript
浅谈Javascript中匀速运动的停止条件
2014/12/19 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
2015/09/09 Javascript
JS实现的简洁纵向滑动菜单(滑动门)效果
2015/10/19 Javascript
Javascript中常用类型的格式化方法小结
2016/12/26 Javascript
前端 Vue.js 和 MVVM 详细介绍
2016/12/29 Javascript
微信小程序商城项目之侧栏分类效果(1)
2017/04/17 Javascript
Vue 页面跳转不用router-link的实现代码
2018/04/12 Javascript
Django+Vue跨域环境配置详解
2018/07/06 Javascript
layui table数据修改的回显方法
2019/09/04 Javascript
JavaScript使用百度ECharts插件绘制饼图操作示例
2019/11/26 Javascript
[05:13]TI4 中国战队 机场出征!!
2014/07/07 DOTA
python图形开发GUI库pyqt5的基本使用方法详解
2020/02/14 Python
Python greenlet和gevent使用代码示例解析
2020/04/01 Python
html5使用canvas压缩图片的示例代码
2018/09/11 HTML / CSS
营销与策划专业毕业生求职信
2013/11/01 职场文书
股东协议书范本
2014/04/14 职场文书
高效课堂标语
2014/06/26 职场文书
幼儿园安全责任书范本
2014/07/24 职场文书
运动会搞笑广播稿
2014/10/14 职场文书
大学生个人学习总结
2015/02/15 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
爱护环境建议书
2015/09/14 职场文书
教师学习心得体会范文
2016/01/21 职场文书
Python Django获取URL中的数据详解
2021/11/01 Python
Redis特殊数据类型Geospatial地理空间
2022/06/01 Redis
MySQL 原理与优化之Update 优化
2022/08/14 MySQL