在Python中实现函数重载的示例代码

yipeiwu_com5年前Python基础

假设你有一个函数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)

我们运行一下这段代码,大家看看根据参数的不同,有什么样的不同效果:

可以看到,我们调用的函数,始终都是 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 对多个csv文件分别进行处理的方法

如下所示: import glob import time import csv csvx_list = glob.glob('*.csv') #打开文件夹下全部的CSV文件 pr...

Python实现拷贝/删除文件夹的方法详解

本文实例讲述了Python实现拷贝 删除文件夹的方法。分享给大家供大家参考,具体如下: 1. 拷贝文件夹 from shutil import copytree, ignore_pa...

浅谈python中真正关闭socket的方法

close方法可以释放一个连接的资源,但是不是立即释放,如果想立即释放,那么在close之前使用shutdown方法 shut_rd() -------关闭接受消息通道 shut_wr(...

python通过cookie模拟已登录状态的初步研究

python通过cookie模拟已登录状态的初步研究

对于那些需要在登录环境下进行的爬虫操作,模拟登陆或伪装已登录状态是一个刚需。 分析了网上关于模拟登录的例子,很多都基于用户名/密码发起一个post请求,遇到有图片验证码的,比较理想的方法...

python 梯度法求解函数极值的实例

如下所示: #coding utf-8 a=0.001 #定义收敛步长 xd=1 #定义寻找步长 x=0 #定义一个种子x0 i=0 #循环迭代次数 y=...