Содержание страницы
9.8. functools – Функции высшего порядка и операции с вызываемыми объектами¶functools – Higher-order functions and operations on callable objects
Новое в версии 2.5.
Исходный код: 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)) # порядок сортировки с учётом локали
Примеры сортировки и краткое руководство см. в 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])¶ Возвращает новый объект 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.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(): ... """докстринг""" ... 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 похожи на объекты function тем, что они вызываемы, могут быть слабыми ссылками и могут иметь атрибуты.
Есть несколько важных отличий.
Например, атрибуты __name__ и __doc__ не создаются автоматически.
Кроме того, объекты partial, определённые в классах,
ведут себя как статические методы и не превращаются в связанные методы при поиске атрибута экземпляра.