【Python模块】functools —— 作用于可调用对象的高阶函数集合

来源:互联网 发布:java程序员主要做什么 编辑:程序博客网 时间:2024/06/15 06:02

    英文原文出自:https://docs.python.org/2/library/functools.html

    functools 是一系列高阶函数的集合,这些函数可以接受其他函数作为参数或者返回其他函数。一般说来,凡是可被调用的对象,都可以当成这个模块的作用对象。

    functools 模块定义了下面的一系列函数:


functools.cmp_to_key(func)

    cmp_to_key可以将老式风格的比较函数转换成比较关键字函数。这个函数用在接收比较关键字函数作为参数的函数中(比如 sorted()min()max()heapq.nlargest()heapq.nsmallest()itertools.groupby())。因为在Python3中不再支持老式风格的比较函数,这个函数也常被当成把python2的函数转向python3的工具。

    老式风格的比较函数是指,接收两个参数进行比较,如果一个前者小于后者返回一个负数,前者等于后者返回0,前者大于后者返回一个正数。比较关键字函数是指接收一个参数,返回另外一个结果作为排序的关键字。

    应用举例:

from functools import cmp_to_keydef cmfunc(x,y):    if x>y:        return 1    elif x==y:        return 0    else:        return -1seq=[2,1,4,5,3]seq = sorted(seq,key=cmp_to_key(cmfunc))for r in seq:    print r
          输出结果:

hyman@hyman-VirtualBox:~/projects/PythonTs$ python cmp_to_keyTs.py 12345
         查看更多排序的例子或者相关文档请查看Sorting HOW TO.


functools.total_ordering(cls)

   如果一个类中含有一个以上的用于比较的方法,这个类级别的修饰器会补充剩下的部分用于比较的方法,它简化了在类中定义比较方法的繁重工作。

   这个被修饰的类必须定义以下方法之一 __lt__()__le__()__gt__(), or __ge__()另外,该类也必须实现__eq__() 方法。     

   应用举例:

@total_orderingclass Student:    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()))
          我们定义了Student类,只声明了__eq__和__lt__方法,当Student类被total_ordering修饰后,使用dir查看Student的属性,其他剩余的比较函数都被自动定义:

>>> from total_orderingTs import Student>>> dir(Student)['__doc__', '__eq__', '__ge__', '__gt__', '__le__', '__lt__', '__module__']>>> 


functools.reduce(functioniterable[initializer])

   这个函数和reduce的功能一样,它在functools模块创建只是为了使python3向前兼容。

  使用举例:

from functools import reducedef add(x,y):    return x+yprint reduce(add,[1,2,3,4,5])
          reduce的功能是将list中的前两个值作为参数传给add函数,然后将add的结果和第三个值再次传给add函数,以此类推,最终返回一个结果:

hyman@hyman-VirtualBox:~/projects/PythonTs$ python reduceTs.py 15


functools.partial(func[,*args][, **keywords])

         返回一个新的partial(偏函数)对象,partial被调用时就像传给它的func函数带着参数args和keywords被调用一样。如果func也附带了自己的参数,那么它的参数将被追加至args或者keywords中。大概等价于以下代码:

def partial(func, *args, **keywords):    def newfunc(*fargs, **fkeywords):        newkeywords = keywords.copy()        newkeywords.update(fkeywords)        return func(*(args + fargs), **newkeywords)    newfunc.func = func    newfunc.args = args    newfunc.keywords = keywords    return newfun
          partial()通过"冻结"一个函数的部分参数而获取一个偏函数对象,相当于简化了原函数的签名。比如说 partial()可以创建一个行为类似于base为2的int()函数:

>>> from functools import partial>>> basetwo = partial(int, base=2)>>> basetwo.__doc__ = 'Convert base 2 string to an int.'>>> basetwo('10010')18
         应用举例:

from functools import partialdef add(x,y,z):    return x+y+znewadd=partial(add,y=1,z=2)print newadd(3)print newadd(55555)
         我们用partial定义新的函数newadd,但是简化了参数列表,只传入一个参数即可。
 

functools.update_wrapper(wrapper, wrapped[, assigned][, updated])

       使修饰函数更加符合被修饰函数。该函数中的后面可选参数是两组元组,前者用来指定从被修饰函数中获取哪些属性给修饰函数,后者用来指定修饰函数中哪些属性需要更新和被修饰函数一致。这些参数的默认值都是模块级别的约束,如WRAPPER_ASSIGNMENTS (在修饰函数中增加 __name____module__ 和 __doc__这些文档属性)和WRAPPER_UPDATES (更新修饰函数的__dict__属性

       这个函数最主要的用处就是用在装饰器中。如果装饰器中的修饰函数没有被更新,装饰器的返回函数的元数据将会映射修饰函数而非被修饰函数。


functools.wraps(wrapped[, assigned][, updated])

    这个函数作为装饰器,在定义修饰函数的时候可以很方便的激活update_wrapper。它等价于partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)。 
    应用举例:
from functools import wrapsdef decoratorWithoutWraps(f):    def wrapper_func(args):        """wrapper doc"""        return f(args)    return wrapper_func@decoratorWithoutWrapsdef wrapped_func1(args):    """wrapped1 doc"""    passdef decoratorWithWraps(f):    @wraps(f)    def wrapper_func():        """wrapper doc"""        return f()    return wrapper_func@decoratorWithWrapsdef wrapped_func2():    """wrapped2 doc"""    passif __name__ =='__main__':    #without @wraps    print wrapped_func1.__name__    print wrapped_func1.__doc__    #with @wraps    print wrapped_func2.__name__    print wrapped_func2.__doc__
    执行结果:
hyman@hyman-VirtualBox:~/projects/PythonTs$ python wrapperTs.pywrapper_funcwrapper docwrapped_func2wrapped2 doc
    对于修饰器函数前没有使用@wraps的,打印出来的结果是定义的修饰器函数的__name__和__doc__,而对于修饰器前使用@wraps的,打印出来的是被修饰函数的__name__和__doc__,显然后者才是我们期望的。


 Github位置:
https://github.com/HymanLiuTS/PythonTs
克隆本项目:
git clone git@github.com:HymanLiuTS/PythonTs.git
获取本文源代码:
git checkout PL02





















0 0