前一段时间学习了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包裹的更多相关文章

  1. Python中functools模块函数解析

    Python自带的 functools 模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数.换言之,就是能使用该模块对可调用对象进行处理. functools模块函数概览 functool ...

  2. Python使用functools模块中的partial函数生成偏函数

    所谓偏函数即是规定了固定参数的函数,在函数式编程中我们经常可以用到,这里我们就来看一下Python使用functools模块中的partial函数生成偏函数的方法 python 中提供一种用于对函数固 ...

  3. Python中optionParser模块的使用方法[转]

    本文以实例形式较为详尽的讲述了Python中optionParser模块的使用方法,对于深入学习Python有很好的借鉴价值.分享给大家供大家参考之用.具体分析如下: 一般来说,Python中有两个内 ...

  4. Python中的模块介绍和使用

    在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一 ...

  5. Python中time模块详解

    Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...

  6. Python 中包/模块的 `import` 操作

    版权声明:博客为作者原创,允许转载,但必须注明原文地址: https://www.cnblogs.com/byronxie/p/10745292.html 用实例来说明 import 的作用吧. 创建 ...

  7. 正则表达式与Python中re模块的使用

    正则表达式与Python中re模块的使用 最近做了点爬虫,正则表达式使用的非常多,用Python做的话会用到re模块. 本文总结一下正则表达式与re模块的基础与使用. 另外,给大家介绍一个在线测试正则 ...

  8. python中的模块和包

    模块 一 什么是模块 模块就是一组功能的集合体,可以通过导入模块来复用模块的功能. 比如我在同一个文件夹定义两个.py文件,分别命名为A.py和B.py,那么可以通过在A文件里通过import B来使 ...

  9. python中argparse模块用法实例详解

    python中argparse模块用法实例详解 这篇文章主要介绍了python中argparse模块用法,以实例形式较为详细的分析了argparse模块解析命令行参数的使用技巧,需要的朋友可以参考下 ...

随机推荐

  1. WordPress添加个性化的博客宠物的方法

    在很多的网站上都看见过这种效果,于是自己也想试试.看见我网站上的小宠物了吗,就是这种效果. 不多说,方法如下: 工具: 下载地址:http://yunpan.cn/cFUmZB8WWthty 访问密码 ...

  2. ASP.NET Core Web 支付功能接入 微信-扫码支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET Core SDK ...

  3. Oracle/Hive/Impala SQL比较1

    5 Function      指数据库内置的function,不讨论UDF.另外,操作符都不比较了,区别不大.   5.1 数学函数 功能 Oracle Hive Impala ABS 绝对值,有 ...

  4. 【Python】 配置文件相对路径&软件自动执行的工作目录

    今天对监控脚本做了一些变更,然后突然发现监控全部都失效了..排查了半天问题仍然不知所踪.最终发现居然是一个踩过好几次的老坑.. 就是脚本内写的配置文件为了调试方便写成了相对路径,但是在上线时没有意识到 ...

  5. 【Python】 迭代器&生成器

    迭代器 任何一个类,只要其实现了__iter__方法,就算是一个可迭代对象.可迭代对象的__iter__方法返回的对象是迭代器,迭代器类需要实现next方法.一般来说,实现了__iter__方法的类肯 ...

  6. Algorithm --> 二分图最大匹配

     匈牙利算法 二分图:把一个图的顶点划分为两个不相交集 U  和 V ,使得每一条边都分别连接U . V  中的顶点.如果存在这样的划分,则此图为一个二分图. 匹配:在图论中,一个「匹配」(match ...

  7. MySQL使用和操作总结

    简介 MySQL是一种DBMS,即它是一种数据库软件.DBMS可分为两类:一类是基于共享文件系统的DBMS,另一类是基于客户机——服务器的DBMS.前者用于桌面用途,通常不用于高端或更关键应用. My ...

  8. 使用Listview控件显示数据

    1.图像列表控件 ImageList是含有图像对象的集合,可以通过索引或关键字引用该集合中的每个对象. ImageList空间的属性 属性 说明 Images 存储在图像列表中的所有图像 ImageS ...

  9. Android中Activity和Service的数据通讯

    在Android中,我们通常需要Activity跟Service进行通讯,很多人只知道Activity掉用Service,却不知道Service如何将数据返回给Activity.其实Service返回 ...

  10. 巨人大哥谈Java中的Synchronized关键字用法

    巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就 ...