functools 2018/9/13
--------------------------------------------------------------------------------------
1 模块简介
用于高阶函数:
指那些作用于函数或者返回其它函数的函数,通常只要是可以被当做函数调用的对象就是这个模块的目标。
函数:
cmp_to_key 将一个比较函数转换关键字函数;
partial 偏函数;
reduce 同内置reduce函数;
total_ordering,在类装饰器中按照缺失顺序,填充方法;
update_wrapper,更新一个包裹(wrapper)函数,使其看起来更像被包裹(wrapped)的函数;
wraps, 可用作一个装饰器,简化调用update_wrapper的过程;
---------------------------------------------------------------------------------
2 模块使用
2.1 cmp_to_key
将老式的比较函数(comparison function)转换为关键字函数(key function)
---------------------------------------------------------------------------------
2.2 偏函数functools.partial(funName,value,...)
用途:
函数参数值按设定值后固定使用
# 把函数某些参数固定(设置默认值),返回新函数,调用这个新函数会更简单
参数:
funName:函数对象
value:*args和**kw这3个参数
参数类型:
a,b;a,b=None;*args(位置参数),kwargs(keyword参数)
----------------------------------------------------------------------------------
用法:
(1) 位置参数
*******************************************
from functools import partial
def add(a, b=-1, c=-2):
return (a,b,c)
add(1, 2, 3) # (1,2,3)
add_1 = partial(add, 1)
add_1(2, 3) # (1,2,3)
add_2= partial(add,1,2)
add_2(3) # (1,2,3)
*******************************************
# 转换二进制字符串
def int_1(x, base=2):
return int(x, base)
int_1('1000000', base=2) # 64
int_2 = functools.partial(int_1, base=2)
int_2('1000000') # 64
# 相当于:kw = { 'base': 2 };int_1('1000000', **kw)
int_2('1000000', base=10) # 1000000
*******************************************
max_1 = functools.partial(max, 10) # 把10作为*args一部分自动加到左边
max_1(5, 6, 7) # 10
# 相当于:args = (10, 5, 6, 7);max(*args);
*******************************************
(2) 位置参数和keyword参数
import functools
def add(*args, **kwargs):
return "args={};kwargs={}".format(args,kwargs)
print(add(1, 2))
add_1 = functools.partial(add,1,2,3,a=10,b=20,c=30)
print(add_1(4,5,d=40,e=50))
# args=(1, 2);kwargs={}
# args=(1, 2, 3, 4, 5);kwargs={'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50}
----------------------------------------------------------------------------
2.3 reduce(f(x,y),list)#函数 f 必须接收两个参数
# 用途: 对list的每个元素反复调用函数f,并返回最终结果值。
# 原理: 将前2个数据相加作为第一个结果,然后将第一个结果和第三个值相加作为第2个结果,依次类推。
import functools
functools.reduce(lambda x,y:x+y,range(0,6))# 15
#y0=x0+x1=0+1=1
#y1=y0+x2=1+2=3
#y2=y1+x3=3+3=6
#y3=y2+x4=6+4=10
#y4=y3+x5=10+5=15
----------------------------------------------------------------------------
2.4 total_ordering
是一个类装饰器,补充其余的比较方法
类必须至少定义 __lt__(), __le__(),__gt__(),__ge__()其中一个,同时,提供 __eq__()方法
-
实例:
from functools import total_ordering
@total_ordering
class Student:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
def __eq__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) ==
(other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))
-
a = Student("ab", "cd")
b = Student("ab", "cd")
c = Student("ab", "ce")
print("a<b", a<c)#True
print("a<b", c>b)#True
print( "b", a==b)#True
-
----------------------------------------------------------------------------
2.5 wraps 用作一个装饰器,简化调用update_wrapper过程.
# 等价于调用
partial(update_wrapper, wrapped = wrapped, assigned=assigned,updated=updated)
# 实例:
from functools import wraps
import time
def my_decorator(f):
print("1.my_decorator start...")
@wraps(f)
def wrap(*args, **kwargs):
print( "2.decorated func called start == > ")
return f(*args, **kwargs)
print("3.my_decorator end")
return wrap
@my_decorator
def MyFun():
"""MyFun doc writec by tcy shanghai 2018/11/15."""
print ("4.MyFun start...")
time.sleep(2)
print("5.MyFun end.")
# 测试
MyFun()
print('6.MyFun.doc=',MyFun.__doc__)
print('7MyFun.name=',MyFun.__name__)
# 输出结果
# 1.my_decorator start...
# 3.my_decorator end
# 2.decorated func called start == >
# 4.MyFun start...
# 5.MyFun end.
# 6.MyFun.doc= MyFun doc writec by tcy shanghai 2018/11/15.
# 7MyFun.name= MyFun
----------------------------------------------------------------------------