Python partial
functools模块
functools模块是为了高阶函数(该高阶函数的定义为作用于或返回其它函数的函数)而设置的。一般来说,任何可调用的对象在该模块中都可被当做函数而处理。
这是在关于functools模块的功能总结,但很是晦涩,
换句话说,functools模块支持函数式编程,即将自定义的函数引用作为参数传递给functools模块下某一个功能函数,得到一个可执行的函数对象。
partial
functool.partial返回一个调用的partial对象,使用方法按照partial(func, *args, **kwargs)
调用。
其发挥的作用在于固定部分参数,从而减少可调用对象的参数个数
from functools import partialdef spam(a, b, c, d):print(a, b, c, d)s1 = partial(spam, 1) # a = 1
s1(1, 2, 3) # 1, 1, 2, 3s2 = partial(spam, 1, 2, d=12)
s2(1) # 1, 2, 1, 12
可以看出 partial()
固定某些参数并返回一个新的callable对象
。这个新的callable接受未赋值的参数, 然后跟之前已经赋值过的参数合并起来,最后将所有参数传递给原始函数。
例子1:根据一个基点来排序点列表集[^乱序]
# coding: utf-8
from functools import partial
from operator import itemgetter
import mathorigin = (0, 1) # 基点
points = [(7, 1), (6, 3), (3, 3)] # 待排序点集def distance(p1, p2):"""return the distance between p1 and p2"""x1, y1 = p1x2, y2 = p2return math.hypot(x1-x2, y1-y2)sorted_points = sorted(points, key=partial(distance, origin))print(sorted_points) # [(3, 3), (6, 3), (7, 1)]
其实,我们是可以通过sorted(points, key=lambda x: distance(x, origin))
来实现同样的功能
partial专注于设计模式,从而提高代码的健壮性。
例子2:如下代码使用 multiprocessing.apply_async()
来异步计算一个结果值, 然后这个值被传递给一个接受一个result值和一个可选logging参数的回调函数,通过partial固定了log对象。
from functools import partial
from multiprocessing import Pool
import loggingdef output_result(result, logger=None):"""output result"""if logger is not None:logger.debug("%d", result)def add(x, y):return x+yif __name__ == '__main__':args = (1, 2)logging.basicConfig(level=logging.DEBUG)logger = logging.getLogger(__name__)p = Pool() # 工作进程的数量默认使用os.cpu_count()返回的数量p.apply_async(add, args, callback=partial(output_result, logger=logger)) # 异步执行p.close()p.join() # 主进程需等待所有子进程执行完毕才关闭
例子3:用socketserver模块编写一个易用的网络服务器,实现echo功能
from socketserver import TCPServer, StreamRequestHandlerclass TCPEchoHandler(StreamRequestHandler):"""c/s下实现echo请求"""def __init__(self, prefix, *args, **kwargs):self.prefix = prefixsuper(TCPEchoHandler).__init__(self, *args, **kwargs)def handle(self):"""请求处理"""# rfile带有缓冲区, 支持分行读取for line in self.rfile:response = 'server get :{data}'.format(data=line.encode('utf-8'))self.wfile.write(response)if __name__ == '__main__':addr = ('localhost', 10030)server = TCPServer(addr, TCPEchoHandler)server.serve_forever()
假设此时,我们需要额外的为TCPEchoHandler
增加一个属性,按照常识我们可能会这么做:
那如何使得server对象中接收这一属性呢?partial
就派上用场了
server = TCPServer(addr, partial(TCPEchoHandler, prefix=b"TCPEchoHandler: \t"))
*特别说明:
- 大部分的
partial
实现的高阶函数引用是能够采用lambda
表达式来替换的(针对于运行时有产出值的情况, 例如排序用到的sorted
函数的参数key
); partial
与lambda
相比较拥有较高的性能;lambda
语义相对较模糊,可读性不高。
源码分析
在分析源码前,我们必须知道
Python
中函数也是对象,意味着可以为函数对象动态添加属性
>>> def test(key1, key2):pass
>>> type(test)
<class 'function'>
>>> test.kwargs = {'key2': 1}
>>> getattr(test, kwargs)
Traceback (most recent call last):File "<pyshell#45>", line 1, in <module>getattr(test, kwargs)
NameError: name 'kwargs' is not defined
>>> getattr(test, 'kwargs')
{'key2': 1}
通过以上推导可知,将固定参数[^(不定参数或关键字参数)]重载到原函数即可实现partial
这时我们再来查看partial
的源码:
def partial(func, *args, **keywords):"""New function with partial application of the given argumentsand keywords."""if hasattr(func, 'func'):args = func.args + argstmpkw = func.keywords.copy()tmpkw.update(keywords)keywords = tmpkwdel tmpkwfunc = func.funcdef newfunc(*fargs, **fkeywords):newkeywords = keywords.copy()newkeywords.update(fkeywords)return func(*(args + fargs), **newkeywords)newfunc.func = funcnewfunc.args = argsnewfunc.keywords = keywordsreturn newfunc
def add(m, n):return m*nif __name__ == '__main__':p = partial(add, n=10)print(p(1))
newfunc
[^函数对象]将func
、固定的不定参数args、固定的关键字参数keywords
封装为自己的属性,利用闭包
将固定参数与非固定参数(fargs, fkeywords)进行拼接,然后返回该新构造的func
对象的调用。
转载于:https://www.cnblogs.com/kisun168/p/11559960.html
Python partial相关推荐
- python partial函数
Python 提供了一个 functools 的模块,该模块为高阶函数提供支持,partial 就是其中的一个函数,该函数的形式如下: functools.partial(func[,*args][, ...
- python函数局部变量_Python局部函数– functoolspartial()
python函数局部变量 什么是Python局部函数? (What is a Python Partial Function?) Sometimes a function accepts multip ...
- Python基础教程,Python神仙级入门教程(非常详细)
Python 是一门开源免费.通用型的脚本编程语言,它上手简单,功能强大,坚持「极简主义」. Python 类库(模块)极其丰富,这使得 Python 几乎无所不能,不管是传统的 Web 开发.PC ...
- 中科大+快手出品 CIRS: Bursting Filter Bubbles by Counterfactual Interactive Recommender System 代码解析
文章目录 前言 论文介绍: 代码介绍: 代码: 一. CIRS-UserModel-kuaishou.py 0. get_args() 解析参数 1. create_dir() 2. Prepare ...
- ApacheCN《Sklearn 与 TensorFlow 机器学习实用指南》 第11章 项目训练深层神经网络(梯度消失与梯度爆炸,选择初始化,选择激活函数)
原文:https://www.jishux.com/p/52b468ceb5722ca5 第11章 训练深层神经网络 来源:ApacheCN<Sklearn 与 TensorFlow 机器学习实 ...
- Functional Programming函数式编程
概论 在过去的近十年的时间里,面向对象编程大行其道.以至于在大学的教育里,老师也只会教给我们两种编程模型,面向过程和面向对象.孰不知,在面向对象产生之前,在面向对象思想产生之前,函数式编程已经有了数十 ...
- Python偏相关(Partial Correlation)或者部分相关性系数计算实战:偏相关性(Partial Correlation)计算及结果解读
Python偏相关(Partial Correlation)或者部分相关性系数计算实战:偏相关性(Partial Correlation)计算及结果解读 目录
- python functools.wraps functools.partial实例解析
一:python functools.wraps 实例 1. 未使用wraps的实例 #!/usr/bin/env python # coding:utf-8def logged(func):def ...
- python函数编程-偏函数partial function
python函数编程-偏函数partial function 一般的,通过设定函数参数的默认值,可以减低函数调用的难度.比如:int()函数可以把字符串转换成整数: >>> int( ...
最新文章
- 11: facebook原生登录
- python写用用户名密码程序_Python创建用户名和密码程序
- 带卷积核的神经网络的迭代次数与收敛标准的关系
- .NET实现应用程序登录Web页
- Boost:bind绑定作为一个组合的测试程序
- Wireshark个人实战总结
- RMQ(求区间最值问题)
- 贝叶斯定理到贝叶斯滤波器
- IIS 500 错误解决
- 【BZOJ3505】[Cqoi2014]数三角形 组合数
- ModelSim仿真实例教程
- MCMC蒙特卡洛算法
- CTFshow wbe41 教你写脚本
- mysql表删除后恢复
- 推荐系统之itemCF
- 花一个星期时间呕心沥血整理出高频软件测试/自动化测试面试题和答案
- Excel数据快速录入技巧分享
- Mac 终端 oh-my-zsh 配置,内含解决oh-my-zsh 下载不下来的方法
- 盘点数据分析师笔试题 你会做几道?
- 【服务器管理】mount.nfs: Stale file handle的解决办法