zoukankan      html  css  js  c++  java
  • 白学这么多年 Python ?连泛型函数都不会写?

    泛型,如果你尝过java,应该对他不陌生吧。但你可能不知道在 Python 中(3.4+ ),也可以实现 简单的泛型函数。

    在Python中只能实现基于单个(第一个)参数的数据类型来选择具体的实现方式,官方名称 是 single-dispatch。你或许听不懂,说人话,就是可以实现第一个参数的数据类型不同,其调用的函数也就不同。

    singledispatch 是 PEP443 中引入的,如果你对此有兴趣,PEP443 应该是最好的学习文档:https://www.python.org/dev/peps/pep-0443/

    它使用方法极其简单,只要被singledispatch 装饰的函数,就是一个single-dispatch 的泛函数(generic functions)。

    • 单分派:根据一个参数的类型,以不同方式执行相同的操作的行为。
    • 多分派:可根据多个参数的类型选择专门的函数的行为。
    • 泛函数:多个函数绑在一起组合成一个泛函数。

    这边举个简单的例子。

    from functools import singledispatch
    
    @singledispatch
    def age(obj):
        print('请传入合法类型的参数!')
    
    @age.register(int)
    def _(age):
        print('我已经{}岁了。'.format(age))
    
    @age.register(str)
    def _(age):
        print('I am {} years old.'.format(age))
    
    
    age(23)  # int
    age('twenty three')  # str
    age(['23'])  # list
    

    执行结果

    我已经23岁了。
    I am twenty three years old.
    请传入合法类型的参数!
    

    说起泛型,其实在 Python 本身的一些内建函数中并不少见,比如 len()iter()copy.copy()pprint()

    你可能会问,它有什么用呢?实际上真没什么用,你不用它或者不认识它也完全不影响你编码。

    我这里举个例子,你可以感受一下。

    大家都知道,Python 中有许许多的数据类型,比如 str,list, dict, tuple 等,不同数据类型的拼接方式各不相同,所以我这里我写了一个通用的函数,可以根据对应的数据类型对选择对应的拼接方式拼接,而且不同数据类型我还应该提示无法拼接。以下是简单的实现。

    def check_type(func):
        def wrapper(*args):
            arg1, arg2 = args[:2]
            if type(arg1) != type(arg2):
                return '【错误】:参数类型不同,无法拼接!!'
            return func(*args)
        return wrapper
    
    
    @singledispatch
    def add(obj, new_obj):
        raise TypeError
    
    @add.register(str)
    @check_type
    def _(obj, new_obj):
        obj += new_obj
        return obj
    
    
    @add.register(list)
    @check_type
    def _(obj, new_obj):
        obj.extend(new_obj)
        return obj
    
    @add.register(dict)
    @check_type
    def _(obj, new_obj):
        obj.update(new_obj)
        return obj
    
    @add.register(tuple)
    @check_type
    def _(obj, new_obj):
        return (*obj, *new_obj)
    
    print(add('hello',', world'))
    print(add([1,2,3], [4,5,6]))
    print(add({'name': 'wangbm'}, {'age':25}))
    print(add(('apple', 'huawei'), ('vivo', 'oppo')))
    
    # list 和 字符串 无法拼接
    print(add([1,2,3], '4,5,6'))
    

    输出结果如下

    hello, world
    [1, 2, 3, 4, 5, 6]
    {'name': 'wangbm', 'age': 25}
    ('apple', 'huawei', 'vivo', 'oppo')
    【错误】:参数类型不同,无法拼接!!
    

    如果不使用singledispatch 的话,你可能会写出这样的代码。

    def check_type(func):
        def wrapper(*args):
            arg1, arg2 = args[:2]
            if type(arg1) != type(arg2):
                return '【错误】:参数类型不同,无法拼接!!'
            return func(*args)
        return wrapper
    
    @check_type
    def add(obj, new_obj):
        if isinstance(obj, str) :
            obj += new_obj
            return obj
    
        if isinstance(obj, list) :
            obj.extend(new_obj)
            return obj
    
        if isinstance(obj, dict) :
            obj.update(new_obj)
            return obj
    
        if isinstance(obj, tuple) :
            return (*obj, *new_obj)
    
    print(add('hello',', world'))
    print(add([1,2,3], [4,5,6]))
    print(add({'name': 'wangbm'}, {'age':25}))
    print(add(('apple', 'huawei'), ('vivo', 'oppo')))
    
    # list 和 字符串 无法拼接
    print(add([1,2,3], '4,5,6'))
    

    输出如下

    hello, world
    [1, 2, 3, 4, 5, 6]
    {'name': 'wangbm', 'age': 25}
    ('apple', 'huawei', 'vivo', 'oppo')
    【错误】:参数类型不同,无法拼接!!
    

    推荐下我本人原创的 《PyCharm 中文指南》电子书,内含大量(300张)的图解制作之精良,值得每个 Python 工程师点个收藏。

    地址是:http://pycharm.iswbm.com

  • 相关阅读:
    二叉查找中使用位运算符
    Python2021专业版激活码
    南邮计算机方向
    7.字符串、异常处理、文件和流(C++学习笔记)
    6.多态与抽象(C++学习笔记)
    5.对象类与继承(C++学习笔记)
    4.数组与指针(C++学习笔记)
    3.C++函数(C++学习笔记)
    2.C++控制语句(C++学习笔记)
    1.基本知识(C++学习笔记)
  • 原文地址:https://www.cnblogs.com/wongbingming/p/13798567.html
Copyright © 2011-2022 走看看