全国咨询热线:400-618-4000

偏函数是什么?Functools模块偏函数详解

创建时间:2019年09月12日16时34分

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) #

print(add) #

# 通过结果验证: 当我们使用 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')

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


推荐了解:
python+人工智能课程
大数据培训课程