• functools模块中的函数


    • Python自带的functools模块提供了一些常用的高阶函数,也就是用于处理其它函数的特殊函数。换言之,就是能使用该模块对可调用对象进行处理。functools模块函数概览functools.cmp_to_key(func)functools.total_ordering(cls)functools.reduce(function,iterable[,initializer])functools.partial(func[,args][,*keywords])functo

    • 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() 都可作为关键字函数。


      在 Python 3 中,有很多地方都不再支持旧式的比较函数,此时可以使用 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 
      class 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())) 


      functools.reduce()


      语法:


      functools.reduce(function, iterable[, initializer])  


      该函数与 Python 内置的 reduce() 函数相同,主要用于编写兼容 Python 3 的代码。


      functools.partial()


      语法:


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


      该函数返回一个 partial 对象,调用该对象的效果相当于调用 func 函数,并传入位置参数 args 和关键字参数 keywords 。如果调用该对象时传入了位置参数,则这些参数会被添加到 args 中。如果传入了关键字参数,则会被添加到 keywords 中。


      partial() 函数的等价实现大致如下:




      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 newfunc 


      partial() 函数主要用于“冻结”某个函数的部分参数,返回一个参数更少、使用更简单的函数对象。


      示例:




      >>> from functools import partial 
      >>> basetwo = partial(int, base=2) 
      >>> basetwo.__doc__ = 'Convert base 2 string to an int.' 
      >>> 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)。


      示例:




      >>> from functools import wraps 
      >>> def my_decorator(f): 
      ... @wraps(f) 
      ... def wrapper(*args, **kwds): 
      ... print 'Calling decorated function' 
      ... return f(*args, **kwds) 
      ... return wrapper 

      >>> @my_decorator 
      ... def example(): 
      ... """Docstring""" 
      ... print 'Called example function' 

      >>> example() 
      Calling decorated function 
      Called example function 
      >>> example.__name__ 
      'example' 
      >>> example.__doc__ 
      'Docstring' 



      如果不使用这个函数,示例中的函数名就会变成 wrapper ,并且原函数 example() 的说明文档(docstring)就会丢失。

    补充:partial方法

    python 中提供一种用于对函数固定属性的函数(与数学上的偏函数不一样)

    # 通常会返回10进制
    int('12345')  # print 12345 
     
    # 使用参数 返回 8进制
    int('11111', 8)  # print 4681

    每次都得添加参数比较麻烦, functools提供了partial的方法

    import functools
     
    foo = functools.partial(int, base=8)
     
    foo('11111')  # print 4681
    通过这种方法生成一个固定参数的新函数
    假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去:
    def int2(x, base=2):
      return int(x, base)

    这样,我们转换二进制就非常方便了:

    >>> int2('1000000')
    64
    >>> int2('1010101')
    85

    functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

    复制代码
    >>> import functools
    >>> int2 = functools.partial(int, base=2)
    >>> int2('1000000')
    64
    >>> int2('1010101')
    85
    复制代码

    所以,简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

    注意到上面的新的int2函数,仅仅是把base参数重新设定默认值为2,但也可以在函数调用时传入其他值:

    >>> int2('1000000', base=10)
    1000000

    最后,创建偏函数时,实际上可以接收函数对象、*args和**kwargs这3个参数,当传入:

    int2 = functools.partial(int, base=2)

    实际上固定了int()函数的关键字参数base,也就是:

    int2('10010')

    相当于:

    kw = { 'base': 2 }
    int('10010', **kwargs)

    当传入:

    max2 = functools.partial(max, 10)

    实际上会把10作为*args的一部分自动加到左边,也就是:

    max2(5, 6, 7)

    相当于:

    args = (10, 5, 6, 7)
    max(*args)
  • 相关阅读:
    【Rust】文件操作
    【Rust】转义字符
    【Rust】原始标识符
    【Rust】字节数组
    【Rust】文档测试
    【Rust】外部函数接口
    【Rust】不安全操作
    【Rust】单元测试
    【Rust】集成测试
    WPF之ComboBox 安静点
  • 原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9438983.html
Copyright © 2020-2023  润新知