9.8. functools — 可调用对象上的高阶函数和操作 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/functools
跳转至:导航、​搜索

9.8. 功能工具 — 可调用对象上的高阶函数和操作

2.5 版中的新功能。


源代码: :source:`Lib/functools.py`



functools 模块用于高阶函数:作用于或返回其他函数的函数。 通常,出于此模块的目的,任何可调用对象都可以视为函数。

functools 模块定义了以下函数:

functools.cmp_to_key(func)

将旧式比较函数转换为 键函数 。 与接受关键函数的工具一起使用(例如 sorted()min()max()heapq.nlargest() ]、heapq.nsmallest()itertools.groupby())。 此函数主要用作转换为不再支持比较函数的 Python 3 的程序的转换工具。

比较函数是任何可调用的函数,它接受两个参数,对它们进行比较,并在小于时返回负数,相等时返回零,或大于时返回正数。 键函数是一个可调用的函数,它接受一个参数并返回另一个用作排序键的值。

例子:

sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order

有关排序示例和简短的排序教程,请参阅 Sorting HOW TO

2.7 版中的新功能。

functools.total_ordering(cls)

给定一个定义一个或多个丰富的比较排序方法的类,这个类装饰器提供其余的。 这简化了指定所有可能的丰富比较操作所涉及的工作:

该类必须定义 __lt__()__le__()__gt__()__ge__() 之一。 此外,该类应提供 __eq__() 方法。

例如:

@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()))

2.7 版中的新功能。

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

这与 reduce() 的功能相同。 它在此模块中可用,以允许编写与 Python 3 更向前兼容的代码。

2.6 版中的新功能。

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

返回一个新的 部分对象 ,它在调用时的行为类似于使用位置参数 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 newfunc

partial() 用于部分函数应用程序,它“冻结”函数参数和/或关键字的某些部分,从而产生具有简化签名的新对象。 例如, partial() 可用于创建一个可调用的,其行为类似于 int() 函数,其中 base 参数默认为两个:

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
functools.update_wrapper(wrapper, wrapped[, assigned][, updated])

wrapper 函数更新为 wrapped 函数。 可选参数是元组,用于指定将原始函数的哪些属性直接分配给包装函数上的匹配属性,以及使用原始函数的相应属性更新包装函数的哪些属性。 这些参数的默认值是模块级常量 WRAPPER_ASSIGNMENTS(分配给包装函数的 __name____module____doc__,文档字符串)和 WRAPPER_UPDATES(更新包装函数的 __dict__,即 实例字典)。

此函数的主要用途是在 decorator 函数中,这些函数包装装饰函数并返回包装器。 如果包装函数没有更新,返回函数的元数据将反映包装定义而不是原始函数定义,这通常没有帮助。

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

这是一个方便的函数,用于在定义包装函数时调用 update_wrapper() 作为函数装饰器。 相当于partial(update_wrapper, wrapped=wrapped, assigned=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() 的文档字符串将丢失。

9.8.1. 部分的对象

partial 对象是由 partial() 创建的可调用对象。 它们具有三个只读属性:

partial.func
一个可调用的对象或函数。 对 partial 对象的调用将使用新的参数和关键字转发到 func
partial.args
最左边的位置参数将被添加到提供给 partial 对象调用的位置参数之前。
partial.keywords
调用 partial 对象时将提供的关键字参数。

partial 对象类似于 function 对象,因为它们是可调用的、弱可引用的,并且可以具有属性。 有一些重要的区别。 例如,__name____doc__ 属性不是自动创建的。 此外,在类中定义的 partial 对象的行为类似于静态方法,并且在实例属性查找期间不会转换为绑定方法。