0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

python偏函数和泛型函数详解

python爬虫知识分享 来源:python爬虫知识分享 作者:python爬虫知识分享 2022-03-03 16:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

python偏函数

假如一个函数定义了多个位置参数,那你每次调用时,都需要把这些个参数一个一个地传递进去。

比如下面这个函数,是用来计算 x的n次方 的。

def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

那我每次计算 x 的 n 次方,都要传递两个参数

>>> power(2, 2)
4
>>> power(3, 2)
9

后来我发现,我很多时候都是计算平方值,很多会去计算三次方,四次方。

那有什么办法可以偷个懒吗?

答案是,有。可以使用 偏函数

偏函数(Partial Function),可以将某个函数的常用参数进行固定,避免每次调用时都要指定。

使用偏函数,需要导入 functools.partial ,然后利用它创建一个新函数,新函数的 n 固定等2。

具体使用请看下面的示例

>>> from functools import partial
>>> power_2=partial(power, n=2)
>>> power_2(2)
4
>>> power_2(3)
9

python泛型函数

根据传入参数类型的不同而调用不同的函数逻辑体,这种实现我们称之为泛型。在 Python 中叫做 singledispatch

它使用方法极其简单,只要被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')
【错误】:参数类型不同,无法拼接!!

审核编辑:符乾江

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66819
  • python
    +关注

    关注

    57

    文章

    4857

    浏览量

    89559
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    使用函数块实现三相电机正反转控制

    在使用西门子S1200PLC,所使用的软件是博途软件,在这个软件里运用了块的概念。比如我们常见的组织块(OB)、函数块(FB)、数据块(DB)以及函数FC等。今天我们来具体交流一下这个函数块(FB)的具体使用方法。
    的头像 发表于 10-15 14:40 2314次阅读
    使用<b class='flag-5'>函数</b>块实现三相电机正反转控制

    详解hal_entry入口函数

    当使用RTOS时,程序从main函数开始进行线程调度;当没有使用RTOS时,C语言程序的入口函数main函数调用了hal_entry函数。由于我们新建的工程是没有选用RTOS的,因此,
    的头像 发表于 07-25 15:34 1660次阅读

    C语言中的内联函数与宏

    在C编程中,内联函数和宏都用于避免函数调用的开销并编写可复用的逻辑部分,但它们在工作方式和安全性方面存在显著差异。
    的头像 发表于 07-25 15:10 1707次阅读
    C语言中的内联<b class='flag-5'>函数</b>与宏

    MSP430常用内联函数说明

    电子发烧友网站提供《MSP430常用内联函数说明.docx》资料免费下载
    发表于 06-05 17:20 0次下载

    为什么不需要给回调函数传递参数

    回调函数是C语言里面一个重要机制。
    的头像 发表于 04-15 10:11 620次阅读

    函数指针的六个常见应用场景

    函数指针在嵌入式开发中有着广泛的应用,它让代码更加灵活,减少冗余,提高可扩展性。很多时候,我们需要根据不同的情况动态调用不同的函数,而函数指针正是实现这一需求的重要工具。本文将介绍六个常见的
    的头像 发表于 04-07 11:58 1119次阅读
    <b class='flag-5'>函数</b>指针的六个常见应用场景

    详解RTOS中的Hook函数

    Hook函数是RTOS中的一个关键特性,通过该函数,用户可以增强对任务管理的控制,定义系统行为。
    的头像 发表于 03-24 16:14 828次阅读

    解锁TSMaster fifo函数:报文读取的高效方法

    前言:TSMaster目前有两种读取报文的模式:回调函数模式和fifo模式。fifo函数是TSMaster近期新增的函数,本文将重点介绍fifo模块。关于回调函数的使用方法可以参考帮助
    的头像 发表于 03-14 20:04 935次阅读
    解锁TSMaster fifo<b class='flag-5'>函数</b>:报文读取的高效方法

    是德33220A 函数任意波形发生器

    是德33220A 函数任意波形发生器 仪器特性 *33220A 函数发生器包括 USB、GPIB 和 LAN 接口 *用于信号设置视觉验证的图形模式 *选件 001 提供支持同步信道的多元链路
    的头像 发表于 02-07 15:55 658次阅读

    C语言如何处理函数的返回值

    当你在函数的最后写上 return 0 的时候,它是如何返回给调用函数的? 比如 test 函数,为了待会更好的看懂汇编代码,我写成了 return 1234。 处理函数的返回值,是不
    的头像 发表于 01-16 09:21 748次阅读

    西门子TIA Portal中函数FC和函数块FB的相互转换

    描述 本文将介绍在西门子 TIA Portal 中使用 Add-In 插件实现函数 FC 和函数块 FB 的相互转换的方法和步骤。 第1步: 添加 PLC 设备。 选择西门子 CPU 1214C
    的头像 发表于 01-15 10:07 3033次阅读
    西门子TIA Portal中<b class='flag-5'>函数</b>FC和<b class='flag-5'>函数</b>块FB的相互转换

    如何把两个数据返回给调用函数

    函数的处理结果包含两个数据,如何把两个数据返回给调用函数? 第一种,把两个数据封装成一个结构体,函数返回结构体。 调用函数的地方同样用结构体去接收
    的头像 发表于 01-08 10:15 677次阅读

    关联接口函数与libmodbus移植

    可以发现,除了modbus.h包含的接口函数之外,modbus-rtu.h和modbus-tcp.h也包含了必要的接口函数
    的头像 发表于 12-30 15:20 1779次阅读
    关联接口<b class='flag-5'>函数</b>与libmodbus移植

    stdio.h实现了printf函数?

    我们平时包含的 stdio.h 头文件,里面是不是实现了 printf 函数? 为什么会有这个疑问?因为每次使用 printf,就得包含 stdio.h ,这就导致很多同学误以为,stdio.h
    的头像 发表于 12-18 10:28 866次阅读

    各类Modbus功能接口函数详解

    函数对应于功能码01(0x01)读取线圈/离散量输出状态(Read CoilStatus/DOs),其中,所读取的值存放于参数uint8_t * dest指向的数组空间因此dest指向的空间必须足够大,其大小至少为nb * sizeof(uint8_t)个字节。
    的头像 发表于 12-11 17:12 3438次阅读
    各类Modbus功能接口<b class='flag-5'>函数</b><b class='flag-5'>详解</b>