Содержание страницы
9.8. functools – Функции высшего порядка и операции с вызываемыми объектами¶functools – Higher order functions and operations on callable objects
Модуль functools предназначен для функций высшего порядка: функций, которые действуют на другие функции или возвращают их. В общем случае любой вызываемый объект можно рассматривать как функцию для целей этого модуля.
Модуль functools определяет следующие функции:
- functools.partial(func, *args, **keywords)¶
Возвращает новый объект partial, который при вызове будет вести себя как func, вызванная с позиционными аргументами args и именованными аргументами keywords. Если в вызов передаётся больше аргументов, они добавляются к 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.reduce(function, iterable[, initializer])¶
- Применяет function с двумя аргументами последовательно к элементам sequence слева направо, сводя последовательность к одному значению. Например, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) вычисляет ((((1+2)+3)+4)+5). Левый аргумент, x, является накопленным значением, а правый аргумент, y, – обновляемым значением из sequence. Если присутствует необязательный initializer, он помещается перед элементами последовательности в вычислении и служит значением по умолчанию, когда последовательность пуста. Если initializer не задан и sequence содержит только один элемент, возвращается первый элемент.
- functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)¶
Обновляет функцию-обёртку так, чтобы она выглядела как обёрнутая функция. Необязательные аргументы – кортежи, определяющие, какие атрибуты исходной функции напрямую присваиваются соответствующим атрибутам функции-обёртки и какие атрибуты функции-обёртки обновляются соответствующими атрибутами исходной функции. Значения по умолчанию для этих аргументов – константы уровня модуля WRAPPER_ASSIGNMENTS (которая присваивает функции-обёртке атрибуты __name__, __module__, __annotations__ и __doc__, т.е. строку документации) и WRAPPER_UPDATES (которая обновляет у функции-обёртки атрибут __dict__, т.е. словарь экземпляра).
Основное назначение этой функции – использование в decorator-функциях, которые оборачивают декорированную функцию и возвращают обёртку. Если функция-обёртка не обновляется, метаданные возвращаемой функции будут отражать определение обёртки, а не исходной функции, что обычно не очень полезно.
- functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)¶
Это удобная функция для вызова 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(): ... """докстринг""" ... print('Called example function') ... >>> example() Calling decorated function Called example function >>> example.__name__ 'example' >>> example.__doc__ 'Docstring'
Без использования этой фабрики декораторов имя примерной функции было бы 'wrapper', а строка документации исходной example() была бы потеряна.
9.8.1. partial Объекты¶partial Objects
partial объекты – это вызываемые объекты, создаваемые с помощью partial(). Они имеют три атрибута только для чтения:
- partial.func¶
- Вызываемый объект или функция. Вызовы объекта partial будут перенаправлены к func с новыми аргументами и ключевыми словами.
- partial.args¶
- Крайние слева позиционные аргументы, которые будут добавлены в начало позиционных аргументов, передаваемых при вызове объекта partial.
- partial.keywords¶
- Ключевые аргументы, которые будут предоставлены, когда объект partial будет вызван.
Объекты partial похожи на объекты function в том, что они являются вызываемыми, могут быть слабыми ссылками и могут иметь атрибуты. Есть несколько важных отличий. Например, атрибуты __name__ и __doc__ не создаются автоматически. Кроме того, объекты partial, определённые в классах, ведут себя как статические методы и не превращаются в связанные методы при поиске атрибутов экземпляра.