详解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 相关文章推荐
下载给定网页上图片的方法
Feb 18 Python
跟老齐学Python之总结参数的传递
Oct 10 Python
11个并不被常用但对开发非常有帮助的Python库
Mar 31 Python
详解Python中的相对导入和绝对导入
Jan 06 Python
视觉直观感受若干常用排序算法
Apr 13 Python
Python使用struct处理二进制的实例详解
Sep 11 Python
python numpy 显示图像阵列的实例
Jul 02 Python
将python图片转为二进制文本的实例
Jan 24 Python
Python列表的切片实例讲解
Aug 20 Python
django自带serializers序列化返回指定字段的方法
Aug 21 Python
python3将变量输入的简单实例
Aug 19 Python
最新pycharm安装教程
Nov 18 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
深入php数据采集的详解
2013/06/02 PHP
基于simple_html_dom的使用小结
2013/07/01 PHP
php中的比较运算符详解
2013/10/28 PHP
PHP入门教程之日期与时间操作技巧总结(格式化,验证,获取,转换,计算等)
2016/09/11 PHP
php版微信自定义回复功能示例
2016/12/05 PHP
PHP缩略图生成和图片水印制作
2017/01/07 PHP
PHP设计模式之装饰器模式实例详解
2018/02/07 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
2019/11/25 PHP
JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句
2012/02/27 Javascript
JS将秒换成时分秒实现代码
2013/09/03 Javascript
js中实现多态采用和继承类似的方法
2014/08/22 Javascript
node.js中的emitter.emit方法使用说明
2014/12/10 Javascript
javascript实现删除前弹出确认框
2015/06/04 Javascript
jQuery预加载图片常用方法
2015/06/15 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
Bootstrap编写一个兼容主流浏览器的受众门户式风格页面
2016/07/01 Javascript
javascript基础知识讲解
2017/01/11 Javascript
jQuery插件JWPlayer视频播放器用法实例分析
2017/01/11 Javascript
一个Js文件函数中调用另一个Js文件函数的方法演示
2017/08/14 Javascript
图文介绍Vue父组件向子组件传值
2018/02/17 Javascript
vue 之 .sync 修饰符示例详解
2018/04/21 Javascript
NodeJS使用Range请求实现下载功能的方法示例
2018/10/12 NodeJs
Vue 页面状态保持页面间数据传输的一种方法(推荐)
2018/11/01 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
Python 正则表达式入门(中级篇)
2016/12/07 Python
Python用 KNN 进行验证码识别的实现方法
2018/02/06 Python
用python与文件进行交互的方法
2018/03/01 Python
python 正确保留多位小数的实例
2018/07/16 Python
python实现C4.5决策树算法
2018/08/29 Python
Django框架反向解析操作详解
2019/11/28 Python
tensorflow 固定部分参数训练,只训练部分参数的实例
2020/01/20 Python
Python HTMLTestRunner可视化报告实现过程解析
2020/04/10 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
2020/06/02 Python
波兰化妆品和护肤品购物网站:eKobieca
2019/08/30 全球购物
毕业生造价工程师求职信
2013/10/17 职场文书
小学生校园广播稿
2014/09/28 职场文书