functools模块之偏函数

1. 偏函数是什么

​ 先回顾一下我们使用函数的过程。首先我们先定义一个函数,如

def func():
    print("in func")

然后我们调用这个函数,即执行代码, 如

func()  # 将会打印出 in func

接下来我们说一说偏函数。

​ 搭噶好我是 C 哥。

​ 假设我通过学习编程走上人生巅峰,腰缠万贯,接下来需要购置房产安家平天下。接下来我们的时间很宝贵,我不太可能把自己投入到 看盘、选盘、议价、交定金、签合同、过户等耗费时间的事情上。此时我可能会考虑请一个房产中介来帮助完成这一系列事情。

​ 所谓偏函数,通俗解释偏函数就是我们的一个房产中介。不管是我自己还是房产中介买房做的步骤其实都是一样,只是是中介花时间去完成的。

这就好比有一个买房的函数

def 为C哥买房(身份证,无房证明,单身证明):
    print("开始买房")

如果是我们自己亲力亲为则需要这样调用

我.为C哥买房('身份证号码','证明房产的证据','证明单身的证据')

2. 使用方式

​ 接下来我们来看看偏函数的使用方式。先回到故事,我先把买房操作需要的数据交给中介公司,然后由中介公司的一个员工替我执行这个买房操作即可。

小张 = 中介公司('身份证号码','证明房产的证据','证明单身的证据')
小张.为C哥买房()

​ 所以仿函数其实就是一个代理。我们为了更简单的操作,可以使用仿函数代理帮我们去执行一段代码逻辑,当然这个功能所需的参数数据要求我们自己提供,总不能让中介用他的身份证给 C 哥买房吧哈哈哈。

​ 言归正传。看看偏函数的用法。

# 1 创建中介对象 并给这个对象传参 告诉他做什么事情  需要哪些数据
#      partial对象            函数代码入口(函数名)  函数参数 
partial对象 = functools.partial(func, *args, **keywords)

# 2 让中介对象 执行我们委托给他的任务
partial对象()

用法明确了,接下来我们看看具体代码。

from functools import partial  # 导入偏函数

# 定义操作
def add(number1, number2, number3):
    return number1 + number2 + number3

# 定义偏partial函数对象
p = partial(add, 100, 99, 100)

# 调用partial对象 执行功能
print(p())   #  执行结果是 299

然而这并不是偏函数的所有使用方式,以上这种情况太理想。更加实际的情况是这样的。

​ 首先回到故事,有可能 C 哥在委托中介的时候只委托了身份证并没有提供其他证明,那这时候 小张去操作时就会缺少证明。所以当 C 哥去让小张进行买房操作时还应该补齐剩余所需的数据。

​ 回到python代码,同理我们在创建偏函数对象时可以只传入一 部分 参数,在执行偏函数对象时再传入剩余 部分 的参数。(所谓 partial 就是部分的意思,多多理解这里部分的含义)

所以可能代码会变成这样

from functools import partial  # 导入偏函数

# 定义操作
def add(number1,number2,number3):
    return number1 + number2 + number3

# 定义偏partial函数对象
p = partial(add, 100, 99)

# 调用partial对象 执行功能
print(p())      #  报错 因为缺少一个必要的位置参数
print(p(100))   #  执行结果是 299
print(p(101))   #  执行结果是 300

3. 偏函数对象剖析

​ 再次强调一下 偏函数就是一个中介,中介帮我们执行委托的任务,并且要求我们提供任务相关数据。

​ 说到这儿大家就会很好奇偏函数是怎么做到的。

首先当我们创建一个 partial 对象时这个对象只做了一件事就是 保存需要执行的目标代码入口(函数名)。

from functools import partial  # 导入偏函数

# 定义操作
def add(number1,number2,number3):
    return number1 + number2 + number3

# 定义偏partial函数对象
p = partial(add, 100, number2=99)

# 获取对象中保存的 目标代码入口
print(p.func)  # <function add at 0x104483e18>
print(add)     # <function add at 0x104483e18>
# 通过结果验证: 当我们使用 p(100)时会执行 p 对象的__call__方法导致执行 p.func

# 如果想要查看 partial 对象相关参数
print(p.args)       # 获取目标代码 相关的位置参数 (100,)

print(p.keywords)   # 获取目标代码 相关的关键字参数 {'number2': 99}

​ 再次强调一下 偏函数就是一个中介,中介帮我们执行委托的任务,并且要求我们提供任务相关数据。

4. 应用场景

接下来咱们说一说偏函数在实际开发中的应用场景:

​ 偏函数可以提前给函数绑定一部分参数,在执行时再传入另一部分参数显得很简洁。

比如我们有一个函数需要计算两个日期之间的天数。

def getDays(date1, date2):
    实现省略
    return 间隔天数

在很多情况下可能第一个参数就是一个固定的日期 比如
# 求'2019-07-01',现在我想要计算这一天到'2050-01-01'以及 的天数
getDays('2019-07-01', '2050-01-01')

# 求'2019-07-01'到'2020-01-01'以及 的天数
getDays('2019-07-01', '2020-01-01')
getDays('2019-07-01', '2017-01-01')
getDays('2019-07-01', '2017-08-17')

# 如果有偏函数 可以提前提供部分参数  这么写即可
from functools import partial
g1 = partial(getDays, '2019-07-01')
g1('2050-01-01')
g1('2020-01-01')
g1('2017-01-01')
g1('2017-08-17')

# 如果起始日期需要变化   
g2 = partial(getDays, '2018-09-08')
g2('2050-01-01')
g2('2020-01-01')
g2('2017-01-01')
g2('2017-08-17')

而这样提供的语法便利是 函数的默认参数所不能达到的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值