Python中functools模块函数解析
Python自带的functools模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数。换言之,就是能使用该模块对可调用对象进行处理。
functools模块函数概览
- functools.cmp_to_key(func)
- functools.total_ordering(cls)
- functools.reduce(function,iterable[,initializer])
- functools.partial(func[,args][,*keywords])
- functools.update_wrapper(wrapper,wrapped[,assigned][,updated])
- functools.wraps(wrapped[,assigned][,updated])
functools.cmp_to_key()
语法:
functools.cmp_to_key(func)
该函数用于将旧式的比较函数转换为关键字函数。
旧式的比较函数:接收两个参数,返回比较的结果。返回值小于零则前者小于后者,返回值大于零则相反,返回值等于零则两者相等。
关键字函数:接收一个参数,返回其对应的可比较对象。例如sorted(),min(),max(),heapq.nlargest(),heapq.nsmallest(),itertools.groupby()都可作为关键字函数。
在Python3中,有很多地方都不再支持旧式的比较函数,此时可以使用cmp_to_key()进行转换。
示例:
sorted(iterable,key=cmp_to_key(cmp_func))
functools.total_ordering()
语法:
functools.total_ordering(cls)
这是一个类装饰器,用于自动实现类的比较运算。
我们只需要在类中实现__eq__()方法和以下方法中的任意一个__lt__(),__le__(),__gt__(),__ge__(),那么total_ordering()就能自动帮我们实现余下的几种比较运算。
示例:
@total_ordering classStudent: 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()))
functools.reduce()
语法:
functools.reduce(function,iterable[,initializer])
该函数与Python内置的reduce()函数相同,主要用于编写兼容Python3的代码。
functools.partial()
语法:
functools.partial(func[,*args][,**keywords])
该函数返回一个partial对象,调用该对象的效果相当于调用func函数,并传入位置参数args和关键字参数keywords。如果调用该对象时传入了位置参数,则这些参数会被添加到args中。如果传入了关键字参数,则会被添加到keywords中。
partial()函数的等价实现大致如下:
defpartial(func,*args,**keywords): defnewfunc(*fargs,**fkeywords): newkeywords=keywords.copy() newkeywords.update(fkeywords) returnfunc(*(args+fargs),**newkeywords) newfunc.func=func newfunc.args=args newfunc.keywords=keywords returnnewfunc
partial()函数主要用于“冻结”某个函数的部分参数,返回一个参数更少、使用更简单的函数对象。
示例:
>>>fromfunctoolsimportpartial >>>basetwo=partial(int,base=2) >>>basetwo.__doc__='Convertbase2stringtoanint.' >>>basetwo('10010') 18
functools.update_wrapper()
语法:
functools.update_wrapper(wrapper,wrapped[,assigned][,updated])
该函数用于更新包装函数(wrapper),使它看起来像原函数一样。可选的参数是一个元组,assigned元组指定要直接使用原函数的值进行替换的属性,updated元组指定要对照原函数进行更新的属性。这两个参数的默认值分别是模块级别的常量:WRAPPER_ASSIGNMENTS和WRAPPER_UPDATES。前者指定了对包装函数的__name__,__module__,__doc__属性进行直接赋值,而后者指定了对包装函数的__dict__属性进行更新。
该函数主要用于装饰器函数的定义中,置于包装函数之前。如果没有对包装函数进行更新,那么被装饰后的函数所具有的元信息就会变为包装函数的元信息,而不是原函数的元信息。
functools.wraps()
语法:
functools.wraps(wrapped[,assigned][,updated])
wraps()简化了update_wrapper()函数的调用。它等价于partial(update_wrapper,wrapped=wrapped,assigned,updated=updated)。
示例:
>>>fromfunctoolsimportwraps >>>defmy_decorator(f): ...@wraps(f) ...defwrapper(*args,**kwds): ...print'Callingdecoratedfunction' ...returnf(*args,**kwds) ...returnwrapper >>>@my_decorator ...defexample(): ..."""Docstring""" ...print'Calledexamplefunction' >>>example() Callingdecoratedfunction Calledexamplefunction >>>example.__name__ 'example' >>>example.__doc__ 'Docstring'
如果不使用这个函数,示例中的函数名就会变成wrapper,并且原函数example()的说明文档(docstring)就会丢失。