2019/10/11 02-functools之reduce和偏函数**

functools,
把一个函数包装称为wrapper,被包装称为wrapped,
在这之前要提醒一下
装饰器只能用前面已经定义过的函数,后面就不需要了
在这里插入图片描述
如果不用装饰器,这两个打印出来都是wrapper在这里插入图片描述
两个都装饰
在这里插入图片描述
一个wrapper是add,一个wrapper是a在这里插入图片描述
这样name就发生改变
上面改名add,下面是a

在这里插入图片描述
这个fn把wrapper属性和名字都替换掉,等于替换两次
在这里插入图片描述在这里插入图片描述
现在是没有函数调用的,其实是有的,因为print已经打印了在这里插入图片描述
现在就要调用两次在这里插入图片描述
函数调用n次是没有关系的,至少fn是没有关系的
在两次调用的wrapper id 是不一样的(都要重新压栈)

在这里插入图片描述
名称a和名称add 覆盖的不是统一个wrapper,没有关系
在这里插入图片描述
打印id看看在这里插入图片描述
这两次wrapper地址不一样
在这里插入图片描述
内嵌函数每次调用的时候都创建一个临时对象,这个函数不调用就没有出头的日子,因为是在内部,每一次创建地址肯定不一样在这里插入图片描述
有没有调用其实用print看一下就可以
在这里插入图片描述
这一块确实有函数调用,它能把下面的add提上来(用的是这个标识符所对应的对象)在这里插入图片描述
函数对象得有你才能覆盖,这两个其实是一个意思,写在前面不一定先执行,只是一种语法
在这里插入图片描述
这两个其实是用来覆盖下面的名称,各覆盖各的,互不干扰在这里插入图片描述
functools内部挺多的,就是常用的东西并不是很多,functools模块
在这里插入图片描述
偏函数
在这里插入图片描述
reduce消减,大数据用的多一点,大数据往往要统计就是n项变成一项的东西在这里插入图片描述
给函数,给可迭代对象,初始值
把可迭代对象弄成迭代器,如果初始值没有,则拿迭代器的第一个数据,否则就用初始值(总之拿到第一个数据)
就看下面怎么处理了
在这里插入图片描述
如果函数是累加的,相当于从你给的序列里,拿一个数据作为基础数据,从它开始之后,就开始累加,如果第一个数据给了初始数据
如果给了初始数据,类似sum=0,就把第一项数据,第二项数据,跟这个0开始迭代,

在这里插入图片描述

这一部分的意思就是不给初始的值,把你第一个数据拿出来,然后后面加第二个参数在这里插入图片描述
累加靠下面这个
在这里插入图片描述
这里面又是个逻辑,放参数中,但是这个高阶函数,给你写这个是等价的吗,这个高阶函数要几个参数,两个参数,第一个参数是一个基数,每次送进来的值,第二个值一直在变,第二个值就是每次把序列中的值扔给你
这个函数要是看明白了,剩下就没什么大问题
在这里插入图片描述
reduce第一个暂时不知道,第二个写序列(如果这个初始值不写就从这里面拿第一个)在这里插入图片描述
告诉你俩个参,一个是累计值(上一次有消减的,跟上次有关),element一般写x y j
在这里插入图片描述
高阶函数一上来最简单就是lambda
value不写也会把(value+element)得到的结果,带到前面的value,又去x你的元素里面去拿一个

在这里插入图片描述
return可以不要,1+2+3+4=10在这里插入图片描述
如果在后面加一个开始值,就应该得到20在这里插入图片描述
function就是你送进来的东西在这里插入图片描述
值一次次迭代完,元素迭代完以后会把你得到的值,把最后的累加值return给你,reduce就返回了,返回的就是你愿意打印就打印在这里插入图片描述
reduce相当于别人标准库提供的,有类似需求,你就不要自己写了,用它即可,但是用它就需要用到高阶函数

但是如果给的是空序列,next就出了问题
在这里插入图片描述
reduce空序列,初始化不了
在这里插入图片描述
reduce概念很好,能解释什么叫消减的过程
大数据领域做的计算就两样东西,mapreduce(map从一种状态变成另外一种状态,但是数据个数并没有消减,在为数据计算之前做准备,做变形
到reduce阶段,按照统计的要求开始消减)

在这里插入图片描述在这里插入图片描述
偏函数,非常重要,在标准库里面常常看到,非常好用的一个东西,很多人不会用不敢用在这里插入图片描述
偏函数就是把函数部分的参数固定下来(定义好的形参,能不能把参数固定下来,add(x,y)加入把y固定成5),相当于为部分的参数添加了固定的默认值,然后形成一个新的函数返回给你(这个新的函数就只跟没有固定的参数有关),所以用户看到就跟原来的函数不一样,参数列表不一样

是生成新的函数,是对原函数的一次包装

在这里插入图片描述
**阅读一下核心的代码,一看这名字就是高阶函数
偏函数是把一个函数包装了,返回一个新函数给你
**
在这里插入图片描述
既然包装函数,被包装的函数就有很多实参传进来在这里插入图片描述
要把很多真正收集的函数传给func
在这里插入图片描述
就在前面做了一些拦截,增强,跟我们之前写的logger架构是差不多的,其实就是对原函数的增强和包装在这里插入图片描述
偏函数可以收集部分的参数
假设有个函数add,本来是4,5假设y=5.x定义不下来,就把y=5告诉partial偏函数即可
y=5先收集过来,x不知道,用的时候再说

在这里插入图片描述
以后把x补上即可,这就叫部分传参在这里插入图片描述
参数送进来,函数定义先跳过
y=5就变成字典收集到了keywrods关键字,args就是空元组
然后返回一个新的函数,newfunc

在这里插入图片描述
newadd(4)调用newfunc

在这里插入图片描述
fargs=(4,),fkeywords 空字典
内层函数用到了外层函数的变量,形成了闭包

在这里插入图片描述
是个新拷贝在这里插入图片描述
新字典更新,如果传x=4,就更新进去了
在这里插入图片描述
要写y=,否则相当于x=5了,所以这么做是不对的
在这里插入图片描述
否则把fargs改成args
在这里插入图片描述
第一次固定下来,认为位置参数靠左,第二次调用新函数,认为位置参数向右,对于关键字爱写不写无所谓,关键字传参与位置无关
在这里插入图片描述
偏函数就是固定某些东西得到某些东西,python用的字典很多
在这里插入图片描述
newadd还可以等于partial (add,y=5)跳过x,就只能用关键字传参的方式
在这里插入图片描述
后面的更新前面的
在这里插入图片描述在这里插入图片描述
相当于把x进行了两次在这里插入图片描述
在这里插入图片描述在这里插入图片描述7+5
在这里插入图片描述
7+6把原来的5覆盖的
在这里插入图片描述
把之前的覆盖掉
在这里插入图片描述
查看签名
在这里插入图片描述
4是固定x的,newadd新函数只跟5相关,这个5就代表y,只跟想y这个变量相关 在这里插入图片描述在这里插入图片描述
这边相当于y固定下来,有个默认值,这种情况下,y是可以被更新的,有要被替换就只能用关键字传参,keywordonly在这里插入图片描述
这样一写就全部都是keywordonly在这里插入图片描述
这个就必须要求keyword传参在这里插入图片描述
偏函数就确实临时给你产生了一个函数出来,看不懂就把签名打开看,返回新函数不知道怎么传参,签名打出来,你就看懂如何传参了
如果看不懂新函数如何传参,就用inspect.signature看看返回签名是什么

偏函数主要用在wraps
在这里插入图片描述4个参数,缺省值可以假定已经固定好的,愿意改的时候再改,
假如无参装饰器的logger是有两个参数的,恰好两个参数有缺省值,就类似一个无参装饰器
wrapper 包装 w
wrapped被包装 fn

在这里插入图片描述
源头函数拿到包装函数里去
最后把字典的特殊属性更新一下
在这里插入图片描述
添加新属性,然后把wrapper返回的在这里插入图片描述
把包装函数的文档名称这一系列的属性都更新了在这里插入图片描述
改用wraps,wraps开始固定东西
把函数这其他三个东西都固定下来了,返回一个新函数,这个函树就只剩下单参,update_wrapper

在这里插入图片描述
原来的固定了,就剩下其他一个在这里插入图片描述在这里插入图片描述
就只剩下这个参数需要对应在这里插入图片描述
只需要解决wrapper就可以了
通过wraps函数,会有一个返回值,这个返回值其实是一个newfunc,这个newfunc的签名相当于只与wrapper相关。
说是wrapper其实也可以用其他啊的,新的函数的形参爱用什么用什么

在这里插入图片描述
带参装饰器
wraps(fun)的调用就返回newfunc(a)这样一个函数定义

在这里插入图片描述
等于这样
在这里插入图片描述
返回带一参的函数局可以当无参装饰器用在这里插入图片描述
你包装了,给你返回一个包装函数,包装函数调用的时候,传入的参数本质上调用的是func(以前的函数)
在这里插入图片描述
调用的newfunc,包装函数,然后形成的新函数调用原来函数
在这里插入图片描述
定义wraps
拿到wraps作为装饰器

在这里插入图片描述
wrap函数想把w替换掉,用add替换w,函数名和文档都替换掉,这么写不容易理解,在原来的修改
在这里插入图片描述
复制到
在这里插入图片描述wraps也移到下面
在这里插入图片描述
这个函数也拿过来,作为覆盖参数在这里插入图片描述
在这里插入图片描述
先写出wraps的等价
第一层调用fn
在这里插入图片描述
wraps(fn),变成实参传参在这里插入图片描述
新函数可以到函数的签名
在这里插入图片描述
传入fn调用函数之后,给 了w w=new(w)
做装饰器 w=new(w)调用new(w)再赋给w,就会调用内层的函数

args就相当于是一个空元组
在这里插入图片描述
func就等于,w就传入进来了
在这里插入图片描述在这里插入图片描述
再传给wrapper在这里插入图片描述
偏函数就按这个来理解在这里插入图片描述
偏函数就是把一些固定下来的参数都可以当做不存在,剩下的按位置传参即可,这时候把参数凑齐了,原函数就要调用了在这里插入图片描述
偏函数是一直要用的,可以把一些函数从多参的变成单参的,变成单参的函数就可以变成无参装饰器使用,这个东西就是用来凑装饰器的,装饰器正好是单参的,装饰器要用好,偏函数必须要知道
在这里插入图片描述在这里插入图片描述
看这个签名就已经没有xy什么事情了在这里插入图片描述
所以看下签名什么都知道了在这里插入图片描述
装饰器理解了就可以抽象,抽象把这种东西随意加在你所需要的的地方,写出来十分优雅,前面就加个@符号,阅读框架的时候大量使用了装饰器,要想增强某些功能,就把装饰器函数放在前面即可,使用@符号
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值