functoolsHigher-order functions and operations on callable objects可调用对象上的高阶函数和操作

Source code: Lib/functools.py


The functools module is for higher-order functions: functions that act on or return other functions. functools模块用于高阶函数:作用于或返回其他函数的函数。In general, any callable object can be treated as a function for the purposes of this module.一般来说,出于本模块的目的,任何可调用对象都可以被视为函数。

The functools module defines the following functions:functools模块定义以下函数:

@functools.cache(user_function)

Simple lightweight unbounded function cache. 简单的轻量级无界函数缓存。Sometimes called “memoize”.有时被称为“记忆”

Returns the same as lru_cache(maxsize=None), creating a thin wrapper around a dictionary lookup for the function arguments. 返回与lru_cache(maxsize=None)相同的值,在函数参数的字典查找周围创建一个薄包装。Because it never needs to evict old values, this is smaller and faster than lru_cache() with a size limit.因为它从不需要逐出旧值,所以它比具有大小限制的lru_cache()更小更快。

For example:

@cache
def factorial(n):
return n * factorial(n-1) if n else 1
>>> factorial(10) # no previously cached result, makes 11 recursive calls
3628800
>>> factorial(5) # just looks up cached value result
120
>>> factorial(12) # makes two new recursive calls, the other 10 are cached
479001600

New in version 3.9.版本3.9中新增。

@functools.cached_property(func)

Transform a method of a class into a property whose value is computed once and then cached as a normal attribute for the life of the instance. 将类的方法转换为一个属性,该属性的值计算一次,然后在实例的生命周期内缓存为正常属性。Similar to property(), with the addition of caching. 类似于property(),增加了缓存。Useful for expensive computed properties of instances that are otherwise effectively immutable.对于以其他方式有效不可变的实例的昂贵计算属性非常有用。

Example:例子:

class DataSet:
def __init__(self, sequence_of_numbers):
self._data = tuple(sequence_of_numbers)

@cached_property
def stdev(self):
return statistics.stdev(self._data)

The mechanics of cached_property() are somewhat different from property(). cached_property()的机制与property()有些不同。A regular property blocks attribute writes unless a setter is defined. 除非定义了setter,否则常规属性会阻止属性写入。In contrast, a cached_property allows writes.相反,cached_property允许写入。

The cached_property decorator only runs on lookups and only when an attribute of the same name doesn’t exist. cached_property装饰器仅在查找时运行,并且仅在相同名称的属性不存在时运行。When it does run, the cached_property writes to the attribute with the same name. 当它确实运行时,cached_property会写入具有相同名称的属性。Subsequent attribute reads and writes take precedence over the cached_property method and it works like a normal attribute.后续的属性读取和写入优先于cached_property方法,其工作方式与普通属性类似。

The cached value can be cleared by deleting the attribute. 可以通过删除属性来清除缓存的值。This allows the cached_property method to run again.这允许cached_property方法再次运行。

Note, this decorator interferes with the operation of PEP 412 key-sharing dictionaries. 注意,该装饰器会干扰PEP 412密钥共享字典的操作。This means that instance dictionaries can take more space than usual.这意味着实例字典可以比通常占用更多的空间。

Also, this decorator requires that the __dict__ attribute on each instance be a mutable mapping. 此外,该装饰器要求每个实例上的__dict__属性是可变映射。This means it will not work with some types, such as metaclasses (since the __dict__ attributes on type instances are read-only proxies for the class namespace), and those that specify __slots__ without including __dict__ as one of the defined slots (as such classes don’t provide a __dict__ attribute at all).这意味着它将不适用于某些类型,例如元类(因为类型实例上的__dict__属性是类名称空间的只读代理),以及那些指定__slots__而不将__dict__作为定义的插槽之一的类型(因为此类类根本不提供__dict__属性)。

If a mutable mapping is not available or if space-efficient key sharing is desired, an effect similar to cached_property() can be achieved by a stacking property() on top of cache():如果可变映射不可用或需要节省空间的密钥共享,则可以通过在cache()上堆叠property()来实现类似cached_property()的效果:

class DataSet:
def __init__(self, sequence_of_numbers):
self._data = sequence_of_numbers
@property
@cache
def stdev(self):
return statistics.stdev(self._data)

New in version 3.8.版本3.8中新增。

functools.cmp_to_key(func)

Transform an old-style comparison function to a key function. 将旧式比较函数转换为键函数Used with tools that accept key functions (such as sorted(), min(), max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby()). 与接受键函数的工具(如sorted()min()max()heapq.nlargest()heapq.nsmallest()itertools.groupby())一起使用。This function is primarily used as a transition tool for programs being converted from Python 2 which supported the use of comparison functions.该函数主要用作从Python 2转换而来的程序的转换工具,Python 2支持使用比较函数。

A comparison function is any callable that accept two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. 比较函数是任何可调用的函数,它接受两个参数,对它们进行比较,并返回负数表示小于,零表示等于,或正数表示大于。A key function is a callable that accepts one argument and returns another value to be used as the sort key.键函数是一个可调用函数,它接受一个参数并返回另一个值作为排序键。

Example:例如:

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

For sorting examples and a brief sorting tutorial, see Sorting HOW TO.有关排序示例和简短的排序教程,请参阅排序方法

New in version 3.2.版本3.2中新增。

@functools.lru_cache(user_function)
@functools.lru_cache(maxsize=128, typed=False)

Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls. Decorator将函数包装为一个可记忆的可调用函数,该函数最多可保存maxsize的最近调用。It can save time when an expensive or I/O bound function is periodically called with the same arguments.当使用相同的参数定期调用昂贵的函数或I/O绑定函数时,它可以节省时间。

Since a dictionary is used to cache results, the positional and keyword arguments to the function must be hashable.由于字典用于缓存结果,因此函数的位置参数和关键字参数必须是可哈希的。

Distinct argument patterns may be considered to be distinct calls with separate cache entries. 不同的参数模式可以被视为具有独立缓存项的不同调用。For example, f(a=1, b=2) and f(b=2, a=1) differ in their keyword argument order and may have two separate cache entries.例如,f(a=1, b=2)f(b=2, a=1)的关键字参数顺序不同,可能有两个单独的缓存项。

If user_function is specified, it must be a callable. 如果指定了user_function,则它必须是可调用的。This allows the lru_cache decorator to be applied directly to a user function, leaving the maxsize at its default value of 128:这允许lru_cache装饰器直接应用于用户函数,将maxsize保留为其默认值128:

@lru_cache
def count_vowels(sentence):
return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')

If maxsize is set to None, the LRU feature is disabled and the cache can grow without bound.如果maxsize设置为None,则LRU功能将被禁用,缓存可以不受限制地增长。

If typed is set to true, function arguments of different types will be cached separately. 如果typed设置为true,则将分别缓存不同类型的函数参数。If typed is false, the implementation will usually regard them as equivalent calls and only cache a single result. 如果typedfalse,则实现通常将其视为等价调用,并且仅缓存单个结果。(Some types such as str and int may be cached separately even when typed is false.)(某些类型,例如strint,即使在type为false时也可以单独缓存。)

Note, type specificity applies only to the function’s immediate arguments rather than their contents. 注意,类型特异性仅适用于函数的直接参数,而不是其内容。The scalar arguments, Decimal(42) and Fraction(42) are be treated as distinct calls with distinct results. 标量参数Decimal(42)Fraction(42)被视为具有不同结果的不同调用。In contrast, the tuple arguments ('answer', Decimal(42)) and ('answer', Fraction(42)) are treated as equivalent.相反,元组参数('answer', Decimal(42))('answer', Fraction(42))被视为等价的。

The wrapped function is instrumented with a cache_parameters() function that returns a new dict showing the values for maxsize and typed. 包装函数使用cache_parameters()函数进行检测,该函数返回一个新的dict,显示maxsizetyped的值。This is for information purposes only. Mutating the values has no effect.改变值没有效果。仅供参考。改变值没有效果。

To help measure the effectiveness of the cache and tune the maxsize parameter, the wrapped function is instrumented with a cache_info() function that returns a named tuple showing hits, misses, maxsize and currsize.为了帮助测量缓存的有效性并优化maxsize参数,使用cache_info()函数检测包装函数,该函数返回一个命名元组,显示命中、未命中、maxsize和currsize。

The decorator also provides a cache_clear() function for clearing or invalidating the cache.装饰器还提供了一个cache_clear()函数,用于清除或使缓存无效。

The original underlying function is accessible through the __wrapped__ attribute. 原始的底层函数可以通过__wrapped__属性访问。This is useful for introspection, for bypassing the cache, or for rewrapping the function with a different cache.这对于内省、绕过缓存或使用不同的缓存重写函数非常有用。

The cache keeps references to the arguments and return values until they age out of the cache or until the cache is cleared.缓存保留对参数和返回值的引用,直到它们从缓存中过时或清除缓存。

An LRU (least recently used) cache works best when the most recent calls are the best predictors of upcoming calls (for example, the most popular articles on a news server tend to change each day). 当最近的呼叫是即将到来的呼叫的最佳预测时(例如,新闻服务器上最流行的文章往往每天都在变化),LRU(最近使用最少的)缓存工作得最好。The cache’s size limit assures that the cache does not grow without bound on long-running processes such as web servers.缓存的大小限制确保缓存不会在不受长时间运行的进程(如web服务器)限制的情况下增长。

In general, the LRU cache should only be used when you want to reuse previously computed values. 通常,仅当您希望重用以前计算的值时,才应使用LRU缓存。Accordingly, it doesn’t make sense to cache functions with side-effects, functions that need to create distinct mutable objects on each call, or impure functions such as time() or random().因此,缓存具有副作用的函数、需要在每次调用时创建不同可变对象的函数或不纯净的函数(如time()random())是没有意义的。

Example of an LRU cache for static web content:静态web内容的LRU缓存示例:

@lru_cache(maxsize=32)
def get_pep(num):
'Retrieve text of a Python Enhancement Proposal'
resource = 'https://www.python.org/dev/peps/pep-%04d/' % num
try:
with urllib.request.urlopen(resource) as s:
return s.read()
except urllib.error.HTTPError:
return 'Not Found'
>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
... pep = get_pep(n)
... print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

Example of efficiently computing Fibonacci numbers using a cache to implement a dynamic programming technique:使用缓存高效计算斐波那契数以实现动态规划技术的示例:

@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

New in version 3.2.版本3.2中新增。

Changed in version 3.3:版本3.3中更改: Added the typed option.添加了typed选项。

Changed in version 3.8:版本3.8中更改: Added the user_function option.添加了user_function选项。

New in version 3.9.版本3.9中新增。Added the function cache_parameters()添加了函数cache_parameters()

@functools.total_ordering

Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. 给定一个定义了一个或多个丰富比较排序方法的类,该类装饰器提供了其余部分。This simplifies the effort involved in specifying all of the possible rich comparison operations:这简化了指定所有可能的丰富比较操作所涉及的工作:

The class must define one of __lt__(), __le__(), __gt__(), or __ge__(). 该类必须定义以下其中之一:__lt__()__le__()__gt__()__ge__()In addition, the class should supply an __eq__() method.此外,该类应提供一个__eq__()方法。

For example:例如:

@total_ordering
class Student:
def _is_valid_operand(self, other):
return (hasattr(other, "lastname") and
hasattr(other, "firstname"))
def __eq__(self, other):
if not self._is_valid_operand(other):
return NotImplemented
return ((self.lastname.lower(), self.firstname.lower()) ==
(other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other):
if not self._is_valid_operand(other):
return NotImplemented
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))

Note

While this decorator makes it easy to create well behaved totally ordered types, it does come at the cost of slower execution and more complex stack traces for the derived comparison methods. 虽然此装饰器使创建行为良好的完全有序类型变得很容易,但它确实以执行速度较慢和派生比较方法的堆栈跟踪更复杂为代价。If performance benchmarking indicates this is a bottleneck for a given application, implementing all six rich comparison methods instead is likely to provide an easy speed boost.如果性能基准测试表明这是给定应用程序的瓶颈,那么实现所有六种丰富的比较方法可能会提供一个简单的速度提升。

Note

This decorator makes no attempt to override methods that have been declared in the class or its superclasses. 此装饰器不尝试重写在类或其超类中声明的方法。Meaning that if a superclass defines a comparison operator, total_ordering will not implement it again, even if the original method is abstract.这意味着,如果一个超类定义了一个比较运算符,total_ordering将不会再次实现它,即使原始方法是抽象的。

New in version 3.2.版本3.2中新增。

Changed in version 3.4:版本3.4中更改: Returning NotImplemented from the underlying comparison function for unrecognised types is now supported.现在支持从未识别类型的基础比较函数返回NotImplemented

functools.partial(func, /, *args, **keywords)

Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. 返回一个新的分部对象,该对象在调用时的行为类似于使用位置参数args和关键字参数keyword调用的funcIf more arguments are supplied to the call, they are appended to args. 如果向调用提供了更多参数,则会将其附加到argsIf additional keyword arguments are supplied, they extend and override keywords. 如果提供了其他关键字参数,它们将扩展和覆盖keywordsRoughly equivalent to:大致相当于:

def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc

The partial() is used for partial function application which “freezes” some portion of a function’s arguments and/or keywords resulting in a new object with a simplified signature. partial()用于部分函数应用程序,该应用程序“冻结”函数参数和/或关键字的某些部分,从而生成具有简化签名的新对象。For example, partial() can be used to create a callable that behaves like the int() function where the base argument defaults to two:例如,可以使用partial()创建一个可调用函数,其行为类似于int()函数,其中base参数默认为两个:

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18
classfunctools.partialmethod(func, /, *args, **keywords)

Return a new partialmethod descriptor which behaves like partial except that it is designed to be used as a method definition rather than being directly callable.返回一个新的partialmethod描述符,其行为类似于partial,只是它被设计为用作方法定义,而不是可直接调用。

func must be a descriptor or a callable (objects which are both, like normal functions, are handled as descriptors).func必须是描述符或可调用的对象(与普通函数一样,两者都是作为描述符处理的对象)。

When func is a descriptor (such as a normal Python function, classmethod(), staticmethod(), abstractmethod() or another instance of partialmethod), calls to __get__ are delegated to the underlying descriptor, and an appropriate partial object returned as the result.func是一个描述符(例如普通Python函数、classmethod()staticmethod()abstractmethod()partialmethod的另一个实例)时,对__get__的调用被委托给底层描述符,并返回一个适当的partial对象作为结果。

When func is a non-descriptor callable, an appropriate bound method is created dynamically. func是非描述符可调用时,将动态创建适当的绑定方法。This behaves like a normal Python function when used as a method: the self argument will be inserted as the first positional argument, even before the args and keywords supplied to the partialmethod constructor.当用作方法时,它的行为类似于普通Python函数:self参数将作为第一个位置参数插入,甚至在提供给partialmethod构造函数的argskeywords之前。

Example:例子:

>>> class Cell:
... def __init__(self):
... self._alive = False
... @property
... def alive(self):
... return self._alive
... def set_state(self, state):
... self._alive = bool(state)
... set_alive = partialmethod(set_state, True)
... set_dead = partialmethod(set_state, False)
...
>>> c = Cell()
>>> c.alive
False
>>> c.set_alive()
>>> c.alive
True

New in version 3.4.版本3.4中新增。

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

Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. 从左到右,将两个参数的function累积应用于iterable的项,以便将iterable减少为单个值。For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). 例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])计算((((1+2)+3)+4)+5)The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. 左参数x是累积值,右参数y是iterable的更新值。If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. 如果存在可选initializer,则在计算中将其放置在iterable的项之前,并在iterable为空时作为默认值。If initializer is not given and iterable contains only one item, the first item is returned.如果未给定initializer,并且iterable仅包含一项,则返回第一项。

Roughly equivalent to:大致相当于:

def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
value = next(it)
else:
value = initializer
for element in it:
value = function(value, element)
return value

See itertools.accumulate() for an iterator that yields all intermediate values.有关生成所有中间值的迭代器,请参阅itertools.accumulate()

@functools.singledispatch

Transform a function into a single-dispatch generic function.将函数转换为单个调度通用函数

To define a generic function, decorate it with the @singledispatch decorator. 要定义泛型函数,请使用@singledispatch装饰器。When defining a function using @singledispatch, note that the dispatch happens on the type of the first argument:使用@singledispatch,请注意,调度发生在第一个参数的类型上:

>>> from functools import singledispatch
>>> @singledispatch
... def fun(arg, verbose=False):
... if verbose:
... print("Let me just say,", end=" ")
... print(arg)

To add overloaded implementations to the function, use the register() attribute of the generic function, which can be used as a decorator. 要向函数添加重载实现,请使用泛型函数的register()属性,该属性可以用作装饰器。For functions annotated with types, the decorator will infer the type of the first argument automatically:对于带类型注释的函数,装饰器将自动推断第一个参数的类型:

>>> @fun.register
... def _(arg: int, verbose=False):
... if verbose:
... print("Strength in numbers, eh?", end=" ")
... print(arg)
...
>>> @fun.register
... def _(arg: list, verbose=False):
... if verbose:
... print("Enumerate this:")
... for i, elem in enumerate(arg):
... print(i, elem)

For code which doesn’t use type annotations, the appropriate type argument can be passed explicitly to the decorator itself:对于不使用类型注释的代码,可以将适当的类型参数显式传递给装饰器本身:

>>> @fun.register(complex)
... def _(arg, verbose=False):
... if verbose:
... print("Better than complicated.", end=" ")
... print(arg.real, arg.imag)
...

To enable registering lambdas and pre-existing functions, the register() attribute can also be used in a functional form:为了能够注册lambda和预先存在的函数,还可以在函数形式中使用register()属性:

>>> def nothing(arg, verbose=False):
... print("Nothing.")
...
>>> fun.register(type(None), nothing)

The register() attribute returns the undecorated function. register()属性返回未修饰的函数。This enables decorator stacking, pickling, and the creation of unit tests for each variant independently:这使得装饰器能够独立地堆叠、pickling和创建每个变体的单元测试:

>>> @fun.register(float)
... @fun.register(Decimal)
... def fun_num(arg, verbose=False):
... if verbose:
... print("Half of your number:", end=" ")
... print(arg / 2)
...
>>> fun_num is fun
False

When called, the generic function dispatches on the type of the first argument:调用时,泛型函数根据第一个参数的类型进行调度:

>>> fun("Hello, world.")
Hello, world.
>>> fun("test.", verbose=True)
Let me just say, test.
>>> fun(42, verbose=True)
Strength in numbers, eh? 42
>>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
Enumerate this:
0 spam
1 spam
2 eggs
3 spam
>>> fun(None)
Nothing.
>>> fun(1.23)
0.615

Where there is no registered implementation for a specific type, its method resolution order is used to find a more generic implementation. 如果没有特定类型的注册实现,则使用其方法解析顺序来查找更通用的实现。The original function decorated with @singledispatch is registered for the base object type, which means it is used if no better implementation is found.原来的功能用@singledispatch是为基本对象类型注册的,这意味着如果没有更好的实现,就会使用它。

If an implementation is registered to an abstract base class, virtual subclasses of the base class will be dispatched to that implementation:如果实现注册到抽象基类,则基类的虚拟子类将被调度到该实现:

>>> from collections.abc import Mapping
>>> @fun.register
... def _(arg: Mapping, verbose=False):
... if verbose:
... print("Keys & Values")
... for key, value in arg.items():
... print(key, "=>", value)
...
>>> fun({"a": "b"})
a => b

To check which implementation the generic function will choose for a given type, use the dispatch() attribute:要检查泛型函数将为给定类型选择哪个实现,请使用dispatch()属性:

>>> fun.dispatch(float)
<function fun_num at 0x1035a2840>
>>> fun.dispatch(dict) # note: default implementation
<function fun at 0x103fe0000>

To access all registered implementations, use the read-only registry attribute:要访问所有注册的实现,请使用只读registry属性:

>>> fun.registry.keys()
dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,
<class 'decimal.Decimal'>, <class 'list'>,
<class 'float'>])
>>> fun.registry[float]
<function fun_num at 0x1035a2840>
>>> fun.registry[object]
<function fun at 0x103fe0000>

New in version 3.4.版本3.4中新增。

Changed in version 3.7:版本3.7中更改: The register() attribute now supports using type annotations.register()属性现在支持使用类型注释。

classfunctools.singledispatchmethod(func)

Transform a method into a single-dispatch generic function.将方法转换为单个调度泛型函数

To define a generic method, decorate it with the @singledispatchmethod decorator. 要定义泛型方法,请使用@singledispatchmethod装饰器。When defining a function using @singledispatchmethod, note that the dispatch happens on the type of the first non-self or non-cls argument:使用@singledispatchmethod,请注意,调度发生在第一个非self或非cls参数的类型上:

class Negator:
@singledispatchmethod
def neg(self, arg):
raise NotImplementedError("Cannot negate a")
@neg.register
def _(self, arg: int):
return -arg

@neg.register
def _(self, arg: bool):
return not arg

@singledispatchmethod supports nesting with other decorators such as @classmethod. @singledispatchmethod支持与其他装饰器嵌套,例如@classmethodNote that to allow for dispatcher.register, singledispatchmethod must be the outer most decorator. 注意,为了允许dispatcher.registersingledispatchmethod必须是最外层的装饰器。Here is the Negator class with the neg methods bound to the class, rather than an instance of the class:以下是Negator类,其neg方法绑定到该类,而不是该类的实例:

class Negator:
@singledispatchmethod
@classmethod
def neg(cls, arg):
raise NotImplementedError("Cannot negate a")
@neg.register
@classmethod
def _(cls, arg: int):
return -arg

@neg.register
@classmethod
def _(cls, arg: bool):
return not arg

The same pattern can be used for other similar decorators: @staticmethod, @abstractmethod, and others.同样的模式也可以用于其他类似的装饰器:@staticmethod@abstractmethod等。

New in version 3.8.版本3.8中新增。

functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

Update a wrapper function to look like the wrapped function. 更新wrapper函数,使其看起来像wrapped函数。The optional arguments are tuples to specify which attributes of the original function are assigned directly to the matching attributes on the wrapper function and which attributes of the wrapper function are updated with the corresponding attributes from the original function. 可选参数是元组,用于指定原始函数的哪些属性直接分配给包装函数上的匹配属性,以及使用原始函数中的相应属性更新包装函数的哪些属性。The default values for these arguments are the module level constants WRAPPER_ASSIGNMENTS (which assigns to the wrapper function’s __module__, __name__, __qualname__, __annotations__ and __doc__, the documentation string) and WRAPPER_UPDATES (which updates the wrapper function’s __dict__, i.e. the instance dictionary).这些参数的默认值是模块级常数WRAPPER_ASSIGNMENTS(分配给包装函数的__module____name____qualname____annotations____doc__,文档字符串)和WRAPPER_UPDATES(更新包装函数的__dict__,即实例字典)。

To allow access to the original function for introspection and other purposes (e.g. bypassing a caching decorator such as lru_cache()), this function automatically adds a __wrapped__ attribute to the wrapper that refers to the function being wrapped.为了允许出于内省和其他目的访问原始函数(例如,绕过缓存修饰符,如lru_cache()),此函数会自动向包装器添加一个__wrapped__属性,该包装器引用正在包装的函数。

The main intended use for this function is in decorator functions which wrap the decorated function and return the wrapper. 此函数的主要预期用途是在装饰器函数中,该函数包装装饰后的函数并返回包装器。If the wrapper function is not updated, the metadata of the returned function will reflect the wrapper definition rather than the original function definition, which is typically less than helpful.如果包装器函数未更新,则返回函数的元数据将反映包装器定义,而不是原始函数定义,这通常没有多大帮助。

update_wrapper() may be used with callables other than functions. 可以与函数以外的可调用项一起使用。Any attributes named in assigned or updated that are missing from the object being wrapped are ignored (i.e. this function will not attempt to set them on the wrapper function). 忽略正在包装的对象中缺少的在assignedupdated中命名的任何属性(即,此函数不会尝试在包装函数上设置它们)。AttributeError is still raised if the wrapper function itself is missing any attributes named in updated.如果包装函数本身缺少更新中指定的任何属性,则仍会引发AttributeError

New in version 3.2.版本3.2中新增。Automatic addition of the __wrapped__ attribute.自动添加__wrapped__属性。

New in version 3.2.版本3.2中新增。Copying of the __annotations__ attribute by default.默认情况下复制__annotations__属性。

Changed in version 3.2:版本3.2中更改: Missing attributes no longer trigger an AttributeError.缺少的属性不再触发AttributeError

Changed in version 3.4:版本3.4中更改: The __wrapped__ attribute now always refers to the wrapped function, even if that function defined a __wrapped__ attribute. 现在,即使函数定义了一个__wrapped__属性,__wrapped__属性也总是指wrapped函数。(see bpo-17482)

@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

This is a convenience function for invoking update_wrapper() as a function decorator when defining a wrapper function. 这是一个方便的函数,用于在定义包装函数时调用update_wrapper()作为函数装饰器。It is equivalent to partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated). 它相当于partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)For example:例如:

>>> 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'

Without the use of this decorator factory, the name of the example function would have been 'wrapper', and the docstring of the original example() would have been lost.如果不使用此装饰器工厂,示例函数的名称将是'wrapper',并且原始example()的docstring将丢失。

partial Objects对象

partial objects are callable objects created by partial(). partial对象是由partial()创建的可调用对象。They have three read-only attributes:它们有三个只读属性:

partial.func

A callable object or function. 可调用的对象或函数。Calls to the partial object will be forwarded to func with new arguments and keywords.partial对象的调用将使用新参数和关键字转发给func

partial.args

The leftmost positional arguments that will be prepended to the positional arguments provided to a partial object call.将在提供给partial对象调用的位置参数之前的最左边的位置参数。

partial.keywords

The keyword arguments that will be supplied when the partial object is called.调用partial对象时将提供的关键字参数。

partial objects are like function objects in that they are callable, weak referencable, and can have attributes. partial对象类似于function对象,因为它们是可调用的、弱可引用的,并且可以具有属性。There are some important differences. 有一些重要的区别。For instance, the __name__ and __doc__ attributes are not created automatically. 例如,__name____doc__属性不是自动创建的。Also, partial objects defined in classes behave like static methods and do not transform into bound methods during instance attribute look-up.此外,类中定义的partial对象的行为类似于静态方法,在实例属性查找期间不会转换为绑定方法。