请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

在Python中实现函数重载,60%的人都不会

[复制链接]
查看: 50|回复: 0

2万

主题

2万

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
75464
发表于 2020-9-17 01:16 | 显示全部楼层 |阅读模式
假设你有一个函数connect,它有一个参数address,这个参数可能是一个字符串,也可能是一个元组。例如:

我的关键词 在Python中实现函数重载,60%的人都不会  新闻咨询 1880991-20200417143541210-1126881260
我的关键词 在Python中实现函数重载,60%的人都不会  新闻咨询 1880991-20200417143556949-1553476351
  1. connect('123.45.32.18:8080')connect(('123.45.32.18', 8080))复制代码
复制代码
你想在代码里面兼容这两种写法,于是你可能会这样写代码:
  1. 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装饰器实现函数重载。
我们来写一段代码:
  1. from functools import singledispatch@singledispatchdef connect(address):    print(f' 传输参数类型为:{type(address)},不是有效类型')@connect.registerdef _(address: str):    ip, port = address.split(':')    print(f'参数为字符串,IP是:{ip}, 端口是:{port}')@connect.registerdef _(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中实现函数重载,60%的人都不会  新闻咨询 1880991-20200417143321709-1673767846


可以看到,我们调用的函数,始终都是connect,但是由于传入参数的类型不同,它运行的结果也不一样。
我们使用singledispatch装饰一个函数,那么这个函数就是我们将会调用的函数。
这个函数在传入参数不同时的具体实现,通过下面注册的函数来实现。注册的时候使用@我们定义的函数名.register来注册。被注册的函数名叫什么无关紧要,所以这里我都直接使用下划线代替。
被注册的函数的第一个参数,通过类型标注来确定它应该使用什么类型。当我们调用我们定义的函数是,如果参数类型符合某个被注册的函数,那么就会执行这个被注册的函数。如果参数类型不满足任何一个被注册的函数,那么就会执行我们的原函数。
使用类型标注来指定参数类型是从 Python 3.7才引入的新特性。在 Python 3.6或之前的版本,我们需要通过@我们定义的函数名.register(类型)来指定类型,例如:
  1. from functools import singledispatch@singledispatchdef 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就业还是兴趣爱好,记住:项目开发经验永远是核心,如果你没有2020最新python入门到高级实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,里面很多新python教程项目,还可以跟老司机交流讨教!
本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表