Python functools 模块
1、reduce 方法
reduce 方法,顾名思义就是减少,map reduce 应用:大数据
语法: reduce(function, sequence[, initial]) -> value
可迭代对象不能为空;初始值没提供就在可迭代对象中取一个元素。
实例:
from functools import reduce print(reduce(lambda x,y : print(x,y), range(5))) # 0, 1, 2, 3, 4 ''' 0 1 # 第一次取 0、1 None 2 # 第一次的返回值:None、2 None 3 # 第二次的返回值:None、2 None 4 # ...... None ''' print(reduce(lambda x,y : x+y, range(5))) # 0, 1, 2, 3, 4 ''' # 求:0 + 1 + 2 + 3 + 4 0 1 # 取0,1 返回 1 1 2 # 取上面的返回值1,2 返回 3 3 3 # 取上面的返回值3,3 返回 6 6 4 # 取上面的返回值6,4 返回 10 ''' print(reduce(lambda x,y : x+y, range(5), 10)) # 10为初始值,结果为:10+0+1+2+3+4 print(sum(range(5), 10)) nums = [6, 9, 4, 2, 4, 10, 5, 9, 6, 9] print(sum(nums)) # 64 print(reduce(lambda val,x : val + x, nums)) # 64 print(reduce(lambda x,y : x*y, range(1, 6))) # 5的阶乘:120 import math print(math.factorial(5)) # 5的阶乘 print(reduce(lambda x,y : x*y, range(1, 6), 10)) # 10为初始值,结果为:10*120
2、partial 方法
偏函数,把函数部分的参数固定下来,相当于为部分的参数添加了一个固定的默认值,形成一个新的函数并返回,从 partial 生成的新函数,是对原函数的封装。
2.1 partial 伪代码
def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) return func(*args, *fargs, **newkeywords) newfunc.func = func # 动态添加一个属性,记住func newfunc.args = args # 记住args newfunc.keywords = keywords # {} return newfunc
2.2 partial 实例
from functools import partial import inspect def add(x, y, z): return x + y + z newfunc = partial(add, 4) print(newfunc(5, 6)) # 相当于把x固定下来,返回新函数,在传入y、z参数 print(inspect.signature(newfunc)) # 新函数的签名:(y, z) print(newfunc(y=3, z=4)) # 相当于:add(4, y=3, z=4) # 建议定义完偏函数,先查看一下签名 newfunc1 = partial(add, y=4) print(inspect.signature(newfunc1)) # 新函数的签名:(x, *, y=4, z) print(newfunc1(4, z=4)) print(newfunc1(4, y=5, z=6))
from functools import partial def add(x, y, *args) -> int: print(args) return x + y newadd = partial(add, 1, 3, 4, 5) newadd(6) newadd(6, 7) newadd(x=6, y=7)
2.3 wraps 偏函数源码剖析
def update_wrapper(wrapper, wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): for attr in assigned: try: value = getattr(wrapped, attr) except AttributeError: pass else: setattr(wrapper, attr, value) for attr in updated: getattr(wrapper, attr).update(getattr(wrapped, attr, {})) wrapper.__wrapped__ = wrapped return wrapper def wraps(wrapped, assigned = WRAPPER_ASSIGNMENTS, updated = WRAPPER_UPDATES): return partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated) ''' update_wrapper(wrapper, wrapped) 柯里化: update_wrapper(wrapper)(fn) 偏函数: wraps(fn) ——> def newfunc(wrapper) @wraps(fn) '''