python中 functools模块 闭包的两个好朋友partial偏函数和wraps包裹
前一段时间学习了python当中的装饰器,主要利用了闭包的原理。后来呢,又见到了python当中的functools模块,里面有很多实用的功能。今天我想分享一下跟装饰器息息相关的两个函数partial和wraps,这两个好伙伴可以说是非常实用。
1 partial偏函数: 这个函数可以帮助我们对一个接收多个参数的函数绑定其中几个参数,返回一个对象,调用这个对象的时候只传给他剩下的参数就可以。它实现了好像闭包才能实现的功能。有的时候可以代替闭包来使用。
不理解??没关系,听我慢慢说!
比如,我们现在想要编写一个函数帮助我们计算直线在坐标系上的y值。 直线方程y = a*x+b。大家请看代码:
def line( a , b , x ):
return a*x + b if __name__ == '__main__':
y1 = line( 10 , 20 , 30)
y2 = line( 10 , 20 , 35)
y3 = line( 10 , 20 , 7)
这个函数能够帮助我们完成功能,给定直线方程的系数a和b,再给定x就能计算出y。
但是我们发现,如果我们想多次利用同一条直线,比如 y = 10*x+20,我们每次传不同的x进去的时候a和b的值也必须传进去,我们重复做了很多工作。
我们怎么样能获得一条a和b指定的直线呢?我们只传进去x就能获取y,相同的直线不用每次都指定a和b??当然可以,用闭包就能实现!
如果还不会闭包的知识的伙伴,你们可以参考这篇博文学习一下闭包:http://www.cnblogs.com/Lin-Yi/p/7305364.html
我们先用闭包实现,上代码!
def getLine( a , b ):
def line( x ):
return a*x + b
return line if __name__ == '__main__':
line1 = getLine( 10,20 )
y1 = line1(5)
y2 = line1(6)
y3 = line1(7)
在这个闭包例子中,我们调用getLine传入a和b,之后我们拿到了内部的line函数,我们再调用line的时候只要给他传入x就可以,这样我们能重复利用同一条直线。
但是其实编写闭包挺麻烦的,我们要写内涵数外函数,而且很多好伙伴可能不理解闭包是怎么回事。这个时候福利来了!!!!!
我们用partial偏函数来实现一个绑定参数的直线!!看代码!
import functools def line( a, b, x ):
return a*x + b if __name__ == '__main__':
#拿到了 y= 10*x + 20
line1 = functools.partial( line, 10 , 20 ) y1 = line1(30)
y2 = line1(35)
y2 = line1(35)
y3 = line1(40)
本来呢,line函数接收三个参数a b和x,但是用partial,把line函数的引用穿进去,之后跟着两个参数,这就代表我要把line函数的前两个参数绑定我传入的指定数值10和20,然后返回一个对象给了line1
我们再调用line1的时候只要传入x就可以执行line函数了!!!
怎么样!是不是很神奇,我们用partial偏函数绑定了一个函数的部分参数,然后拿到一个函数对象,帮我们实现了闭包才能实现的效果!
2 wraps包裹: 帮助我们实现装饰器中,目标函数对象的属性迁移。
不理解??刚开始我也不理解~ . ~........ 那就听我说说~也许就懂啦!
上一次在探讨装饰器的时候,最后一个例子中留了一个问题没有解决,问题就是,我们用装饰器对目标函数dest进行装饰,用@decorator的时候,把目标函数dest传入了装饰器decorator,装饰器把内部函数inner的引用返回给了目标函数名dest。当我们再调用dest的时候实际上调用了装饰器返回的内部函数inner的实例对象。如果我们查看一下dest.__name__和dest.__doc__等等这些属性,发现我们获得的是inner的属性不是原本我们想要的dest的属性。
看我的描述很糊涂吧,我们来一段代码!看一下,装饰器带来了什么问题:
def decorator(func):
def inner( *args ,**kwargs ):
print("装饰器的前置业务逻辑")
res = func( *args ,**kwargs ) #在这里执行目标函数
print("装饰器的后置业务逻辑")
return res
return inner @decorator #这里相当于发生了 dest = decorator( dest )
# 把目标函数dest传进去给了func,返回来的inner给了dest
def dest(): #之后再执行dest 其实执行了inner
print("这里是目标函数dest") if __name__ == '__main__':
print(dest.__name__) #inner
我们用decorator装饰器对dest目标函数装饰之后,再查看dest.__name__ 却得到了inner,,因为内涵数返回给了dest保存,再调用dest其实就是调用了inner
这是正确的却不是我们想要的。我们抛开装饰器,在外部看来,我们还是想要得到一致性的结果,我指向要我自己的属性,怎么办??
ok!wraps能够帮我们实现属性的迁移!
上一段代码!
import functools
def decorator(func):
#functool模块的wraps函数传入目标函数,他能帮我们把目标函数的所有属性迁移给内涵数
@functools.wraps(func)
def inner( *args ,**kwargs ):
print("装饰器的前置业务逻辑")
res = func( *args ,**kwargs ) #在这里执行目标函数
print("装饰器的后置业务逻辑")
return res
return inner @decorator #这里相当于发生了 dest = decorator( dest )
# 把目标函数dest传进去给了func,返回来的inner给了dest
def dest(): #之后再执行dest 其实执行了inner
print("这里是目标函数dest") if __name__ == '__main__':
#这是再查看属性的时候 就保持了一致性,wraps帮助我们把目标函数的属性迁移了
print(dest.__name__) #dest
和上面的例子只有一行代码的区别,在inner函数前加上了@functools.wraps(func)
把目标函数传给wraps,用wraps对inner进行装饰,它帮助我们把目标函数的属性全都复制过来了。让外部调用者看来保持了一致性!
python中 functools模块 闭包的两个好朋友partial偏函数和wraps包裹的更多相关文章
- Python中functools模块函数解析
Python自带的 functools 模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数.换言之,就是能使用该模块对可调用对象进行处理. functools模块函数概览 functool ...
- Python使用functools模块中的partial函数生成偏函数
所谓偏函数即是规定了固定参数的函数,在函数式编程中我们经常可以用到,这里我们就来看一下Python使用functools模块中的partial函数生成偏函数的方法 python 中提供一种用于对函数固 ...
- Python中optionParser模块的使用方法[转]
本文以实例形式较为详尽的讲述了Python中optionParser模块的使用方法,对于深入学习Python有很好的借鉴价值.分享给大家供大家参考之用.具体分析如下: 一般来说,Python中有两个内 ...
- Python中的模块介绍和使用
在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一 ...
- Python中time模块详解
Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...
- Python 中包/模块的 `import` 操作
版权声明:博客为作者原创,允许转载,但必须注明原文地址: https://www.cnblogs.com/byronxie/p/10745292.html 用实例来说明 import 的作用吧. 创建 ...
- 正则表达式与Python中re模块的使用
正则表达式与Python中re模块的使用 最近做了点爬虫,正则表达式使用的非常多,用Python做的话会用到re模块. 本文总结一下正则表达式与re模块的基础与使用. 另外,给大家介绍一个在线测试正则 ...
- python中的模块和包
模块 一 什么是模块 模块就是一组功能的集合体,可以通过导入模块来复用模块的功能. 比如我在同一个文件夹定义两个.py文件,分别命名为A.py和B.py,那么可以通过在A文件里通过import B来使 ...
- python中argparse模块用法实例详解
python中argparse模块用法实例详解 这篇文章主要介绍了python中argparse模块用法,以实例形式较为详细的分析了argparse模块解析命令行参数的使用技巧,需要的朋友可以参考下 ...
随机推荐
- C语言第九次博客作业--指针
一.PTA实验作业 题目1:两个4位正整数的后两位互换 1. 本题PTA提交列表 2. 设计思路 定义循环变量i,两个数组a[4],b[4] for i=0 to 3 a[i]*p取各个位 *p/=1 ...
- CI框架传递数组到view层问题记录
给大家分享一下在做页面显示天气预报功能中遇到的问题和解决方法!! 项目开发中,我用的天气预报API是心知天气的免费接口.关于天气预报接口,可用的有很多,看需求怎么要求了!有兴趣的小伙伴可以链接到这个地 ...
- C++实验1
- 数据系统的未来------《Designing Data-Intensive Applications》读书笔记17
终于来到这本书最后的一章了<Designing Data-Intensive Applications>大部头,这本书应该是我近两年读过最棒的技术书籍.作者Martin Kleppmann ...
- Angular开发实践(六):服务端渲染
Angular Universal Angular在服务端渲染方面提供一套前后端同构解决方案,它就是 Angular Universal(统一平台),一项在服务端运行 Angular 应用的技术. 标 ...
- python全栈开发-Day9 函数对象、函数嵌套、名称空间与作用域
一 .函数对象 一 .函数是第一类对象,即函数可以当作数据传递 可以被引用 可以当作参数传递 返回值可以是函数 可以当作容器类型的元素 二. 利用该特性,优雅的取代多分支的if def foo(): ...
- 设计模式之 外观模式详解(Service第三者插足,让action与dao分手)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,LZ今天给各位分享一 ...
- attr与prop html与text
- OC实现单选和多选按钮
本代码库暂时有OC封装,改天有空在补一个Swift封装的,主要是因为swift不是那么熟,怕出错,半天找不到问题多尴尬呀! 先附上demo下载地址CSDN:http://download.csdn.n ...
- 从Firefox升级说学习方法
今天早上,打开PortableAPPs时,它提示我升级FireFox,跟往常一样我没考虑就升级了. 打开Firefox 57神速,很是惊喜,打开后发现悲剧了,自己(通过下载插件)定制的功能都不能使用了 ...