详解Python 函数如何重载?


Posted in Python onApril 23, 2019

什么是函数重载?简单的理解,支持多个同名函数的定义,只是参数的个数或者类型不同,在调用的时候,解释器会根据参数的个数或者类型,调用相应的函数。

重载这个特性在很多语言中都有实现,比如 C++、Java 等,而 Python 并不支持。这篇文章呢,通过一些小技巧,可以让 Python 支持类似的功能。

参数个数不同的情形

先看看这种情况下 C++ 是怎么实现重载的

#include <iostream>
using namespace std;

int func(int a)
{
	cout << 'One parameter' << endl;
}

int func(int a, int b)
{
	cout << 'Two parameters' << endl;
}

int func(int a, int b, int c)
{
	cout << 'Three parameters' << endl;
}

如果 Python 按类似的方式定义函数的话,不会报错,只是后面的函数定义会覆盖前面的,达不到重载的效果。

>>> def func(a):
...   print('One parameter')
... 
>>> def func(a, b):
...   print('Two parameters')
... 
>>> def func(a, b, c):
...   print('Three parameters')
... 
>>> func(1)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: func() missing 2 required positional arguments: 'b' and 'c'
>>> func(1, 2)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required positional argument: 'c'
>>> func(1, 2, 3)
Three parameters

但是我们知道,Python 函数的形参十分灵活,我们可以只定义一个函数来实现相同的功能,就像这样

>>> def func(*args):
...   if len(args) == 1:
...     print('One parameter')
...   elif len(args) == 2:
...     print('Two parameters')
...   elif len(args) == 3:
...     print('Three parameters')
...   else:
...     print('Error')
... 
>>> func(1)
One parameter
>>> func(1, 2)
Two parameters
>>> func(1, 2, 3)
Three parameters
>>> func(1, 2, 3, 4)
Error

参数类型不同的情形

同样,先看下当前情况下 C++ 的重载是怎么实现的

#include <iostream>
using namespace std;

int func(int a)
{
	cout << 'Int: ' << a << endl;
}

int func(float a)
{
	cout << 'Float: ' << a << endl;
}

代码中,func 支持两种类型的参数:整形和浮点型。调用时,解释器会根据参数类型去寻找合适的函数。Python 要实现类似的功能,需要借助 functools.singledispatch 装饰器。

from functools import singledispatch

@singledispatch
def func(a):
	print(f'Other: {a}')

@func.register(int)
def _(a):
	print(f'Int: {a}')

@func.register(float)
def _(a):
	print(f'Float: {a}')

if __name__ == '__main__':
	func('zzz')
	func(1)
	func(1.2)

func 函数被 functools.singledispatch 装饰后,又根据不同的参数类型绑定了另外两个函数。当参数类型为整形或者浮点型时,调用绑定的对应的某个函数,否则,调用自身。

执行结果

Other: zzz
Int: 1
Float: 1.2

需要注意的是,这种方式只能够根据第一个参数的类型去确定最后调用的函数。

关于 singledispatch 的更多细节请看官方文档

https://docs.python.org/3.6/library/functools.html#functools.singledispatch

注意:函数返回值不同也是重载的一种情况,暂时没有比较好的 Python 实现方式,所以没有提及

个人觉得,重载就是为了语言的灵活性而设计的,而 Python 函数本来就有不少巧妙的设计,这个时候去仿这个技术,其实没有多大必要,而且感觉有些违背 Python 的哲学。所以,本文更多的是在讲如何模仿,而对于重载的使用场景并没有作多少说明。

以上所述是小编给大家介绍的Python函数重载详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python连接远程ftp服务器并列出目录下文件的方法
Apr 01 Python
python黑魔法之编码转换
Jan 25 Python
python基于http下载视频或音频
Jun 20 Python
详解Python 解压缩文件
Apr 09 Python
Python解析json时提示“string indices must be integers”问题解决方法
Jul 31 Python
django-rest-swagger的优化使用方法
Aug 29 Python
Python 脚本的三种执行方式小结
Dec 21 Python
在django中使用apscheduler 执行计划任务的实现方法
Feb 11 Python
django template实现定义临时变量,自定义赋值、自增实例
Jul 12 Python
Python numpy矩阵处理运算工具用法汇总
Jul 13 Python
Python实现Canny及Hough算法代码实例解析
Aug 06 Python
python温度转换华氏温度实现代码
Dec 06 Python
解决Django生产环境无法加载静态文件问题的解决
Apr 23 #Python
Python 存储字符串时节省空间的方法
Apr 23 #Python
Django页面数据的缓存与使用的具体方法
Apr 23 #Python
Python切片操作去除字符串首尾的空格
Apr 22 #Python
详解python中的hashlib模块的使用
Apr 22 #Python
Python 中包/模块的 `import` 操作代码
Apr 22 #Python
python定时检测无响应进程并重启的实例代码
Apr 22 #Python
You might like
修改destoon会员公司的伪静态中的com目录的方法
2014/08/21 PHP
Yii全局函数用法示例
2017/01/22 PHP
PHP命令空间namespace及use的用法小结
2017/11/27 PHP
JavaScript constructor和instanceof,JSOO中的一对欢喜冤家
2009/05/25 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
2015/03/25 Javascript
javascript中setTimeout使用指南
2015/07/26 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
JS中动态创建元素的三种方法总结(推荐)
2016/10/20 Javascript
基于百度地图实现产品销售的单位位置查看功能设计与实现
2016/10/21 Javascript
JavaScript登录验证码的实现
2016/10/27 Javascript
Node.js 中exports 和 module.exports 的区别
2017/03/14 Javascript
canvas实现环形进度条效果
2017/03/23 Javascript
VueJS事件处理器v-on的使用方法
2017/09/27 Javascript
spirngmvc js传递复杂json参数到controller的实例
2018/03/29 Javascript
jquery的$().each和$.each的区别
2019/01/18 jQuery
简单了解JavaScript中的执行上下文和堆栈
2019/06/24 Javascript
在layui框架中select下拉框监听更改事件的例子
2019/09/20 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
[47:18]完美世界DOTA2联赛循环赛 IO vs FTD BO2第一场 11.05
2020/11/06 DOTA
Python代理抓取并验证使用多线程实现
2013/05/03 Python
python使用代理ip访问网站的实例
2018/05/07 Python
python通过ffmgep从视频中抽帧的方法
2018/12/05 Python
Python多继承以及MRO顺序的使用
2019/11/11 Python
Python Sympy计算梯度、散度和旋度的实例
2019/12/06 Python
新版Pycharm中Matplotlib不会弹出独立的显示窗口的问题
2020/06/02 Python
python自动生成sql语句的脚本
2021/02/24 Python
MUGLER官方网站:蒂埃里·穆勒香水
2019/11/26 全球购物
小学体育教学反思
2014/01/31 职场文书
社会实践先进工作者事迹材料
2014/05/06 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
中药学专业求职信
2014/05/31 职场文书
团党委领导干部党的群众路线教育实践活动个人对照检查材料思想汇
2014/10/05 职场文书
2016年感恩母亲节活动总结
2016/04/01 职场文书
vue3使用vue-router的完整步骤记录
2021/06/20 Vue.js
一篇文章带你学习Mybatis-Plus(新手入门)
2021/08/02 Java/Android
详解在OpenCV中如何使用图像像素
2022/03/03 Python