详解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使用urllib模块开发的多线程豆瓣小站mp3下载器
Jan 16 Python
Python命名空间详解
Aug 18 Python
Python中pygame的mouse鼠标事件用法实例
Nov 11 Python
python2.7无法使用pip的解决方法(安装easy_install)
Apr 03 Python
Python使用爬虫爬取静态网页图片的方法详解
Jun 05 Python
python 怎样将dataframe中的字符串日期转化为日期的方法
Sep 26 Python
关于Pytorch的MLP模块实现方式
Jan 07 Python
浅谈spring boot 集成 log4j 解决与logback冲突的问题
Feb 20 Python
Django Serializer HiddenField隐藏字段实例
Mar 31 Python
python实现时间序列自相关图(acf)、偏自相关图(pacf)教程
Jun 03 Python
Python实现敏感词过滤的4种方法
Sep 12 Python
手残删除python之后的补救方法
Jun 26 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常用ODBC函数集(详细)
2013/06/24 PHP
php全角字符转换为半角函数
2014/02/07 PHP
php教程之phpize使用方法
2014/02/12 PHP
php中count获取多维数组长度的方法
2014/11/03 PHP
php实现改变图片直接打开为下载的方法
2015/04/14 PHP
php基于双向循环队列实现历史记录的前进后退等功能
2015/08/08 PHP
php curl模拟post请求和提交多维数组的示例代码
2015/11/19 PHP
php基于curl主动推送最新内容给百度收录的方法
2016/10/14 PHP
使用jquery插件实现图片延迟加载技术详细说明
2011/03/12 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
Javascript图像处理思路及实现代码
2012/12/25 Javascript
javascript基础之查找元素的详细介绍(访问节点)
2013/07/05 Javascript
教你用AngularJS框架一行JS代码实现控件验证效果
2014/06/23 Javascript
jQuery限制图片大小的方法
2016/05/25 Javascript
省市区三级联动jquery实现代码
2020/04/15 Javascript
jQuery中table数据的值拷贝和拆分
2017/03/19 Javascript
Express URL跳转(重定向)的实现方法
2017/04/07 Javascript
微信小程序实现皮肤功能(夜间模式)
2017/06/18 Javascript
Angular实现下拉框模糊查询功能示例
2018/01/03 Javascript
vue实现微信分享朋友圈,发送朋友的示例讲解
2018/02/10 Javascript
JS实现关键词高亮显示正则匹配
2018/06/22 Javascript
JavaScript实现单英文金山打字通
2020/07/24 Javascript
Vue将props值实时传递 并可修改的操作
2020/08/09 Javascript
如何搭建一个完整的Vue3.0+ts的项目步骤
2020/10/18 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
2021/03/01 Vue.js
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
Python中MySQL数据迁移到MongoDB脚本的方法
2016/04/28 Python
python读取Excel实例详解
2018/08/17 Python
Python提取支付宝和微信支付二维码的示例代码
2019/02/15 Python
Python中断多重循环的思路总结
2019/10/04 Python
python生成器/yield协程/gevent写简单的图片下载器功能示例
2019/10/28 Python
HTML5本地存储和本地数据库实例详解
2017/09/05 HTML / CSS
父亲生日宴会答谢词
2014/01/10 职场文书
班主任开场白
2015/06/01 职场文书
Mysql分库分表之后主键处理的几种方法
2022/02/15 MySQL