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


    假设你有一个函数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)
    
    复制代码
    1. 我们运行一下这段代码,大家看看根据参数的不同,有什么样的不同效果:

     可以看到,我们调用的函数,始终都是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就业还是兴趣爱好,记住:项目开发经验永远是核心,如果你没有2020最新python入门到高级实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,里面很多新python教程项目,还可以跟老司机交流讨教!
    本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

  • 相关阅读:
    通用网络管理方案归纳
    visual studio 中将选中代码相同的代码的颜色设置,修改高亮颜色
    (转)git stash使用
    (转) git--Remote远程仓库的使用
    (转)git checkout 撤销修改
    (转)git中关于fetch的使用
    (转)Visual Studio控制台程序输出窗口一闪而过的解决方法
    (转)sublime text3简体中文版汉化教程
    git使用记录
    (转)Java 中正确使用 hashCode 和 equals 方法
  • 原文地址:https://www.cnblogs.com/chengxuyuanaa/p/12719855.html
Copyright © 2020-2023  润新知