> **Источник:** https://python-all.ru/2.7/library/functools.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 9.8. [`functools`](https://python-all.ru/2.7/library/functools.html#module-functools) – Функции высшего порядка и операции с вызываемыми объектами

Новое в версии 2.5.

**Исходный код:** [Lib/functools.py](https://python-all.ru/src/2.7/Lib/functools.py)

---

Модуль [`functools`](https://python-all.ru/2.7/library/functools.html#module-functools) предназначен для функций высшего порядка: функций, которые действуют на или возвращают другие функции. В общем случае любой вызываемый объект может рассматриваться как функция для целей этого модуля.

Модуль [`functools`](https://python-all.ru/2.7/library/functools.html#module-functools) определяет следующие функции:

#### `functools.cmp_to_key(func)`

Преобразует функцию сравнения старого стиля в [ключевую функцию](https://python-all.ru/2.7/glossary.html#term-key-function). Используется с инструментами, которые принимают ключевые функции (такими как [`sorted()`](https://python-all.ru/2.7/library/functions.html#sorted), [`min()`](https://python-all.ru/2.7/library/functions.html#min), [`max()`](https://python-all.ru/2.7/library/functions.html#max), [`heapq.nlargest()`](https://python-all.ru/2.7/library/heapq.html#heapq.nlargest), [`heapq.nsmallest()`](https://python-all.ru/2.7/library/heapq.html#heapq.nsmallest), [`itertools.groupby()`](https://python-all.ru/2.7/library/itertools.html#itertools.groupby)). Эта функция в основном используется как переходный инструмент для программ, переносимых на Python 3, где функции сравнения больше не поддерживаются.

Функция сравнения – это любой вызываемый объект, который принимает два аргумента, сравнивает их и возвращает отрицательное число, если первый меньше второго, ноль при равенстве или положительное число, если первый больше второго. Функция ключа – это вызываемый объект, который принимает один аргумент и возвращает другое значение, используемое в качестве ключа сортировки.

Пример:

```python
sorted(iterable, key=cmp_to_key(locale.strcoll))  # порядок сортировки с учётом локали
```

Примеры сортировки и краткое руководство см. в [Sorting HOW TO](https://python-all.ru/2.7/howto/sorting.html#sortinghowto).

Новое в версии 2.7.

#### `functools.total_ordering(cls)`

Для класса, определяющего один или несколько методов расширенного сравнения, этот декоратор класса предоставляет остальные. Это упрощает задачу определения всех возможных операций расширенного сравнения:

Класс должен определять один из [`__lt__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__lt__), [`__le__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__le__), [`__gt__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__gt__) или [`__ge__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__ge__). Кроме того, класс должен предоставлять метод [`__eq__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__eq__).

Например:

```python
@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()`](https://python-all.ru/2.7/library/functions.html#reduce). Она доступна в этом модуле, чтобы позволить писать код, более совместимый с будущими версиями Python 3.

Новое в версии 2.6.

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

Возвращает новый [объект partial](https://python-all.ru/2.7/library/functools.html#partial-objects), который при вызове ведёт себя как *func*, вызванная с позиционными аргументами *args* и именованными аргументами *keywords*. Если при вызове передаётся больше аргументов, они добавляются к *args*. Если передаются дополнительные именованные аргументы, они расширяют и переопределяют *keywords*. Примерно соответствует:

```python
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()`](https://python-all.ru/2.7/library/functools.html#functools.partial) используется для частичного применения функции, которое «замораживает» некоторую часть аргументов и/или ключевых слов функции, создавая новый объект с упрощённой сигнатурой. Например, [`partial()`](https://python-all.ru/2.7/library/functools.html#functools.partial) можно использовать для создания вызываемого объекта, который ведёт себя как функция [`int()`](https://python-all.ru/2.7/library/functions.html#int), где аргумент *base* по умолчанию равен двум:

```python
>>> 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](https://python-all.ru/2.7/glossary.html#term-decorator)-функциях, которые оборачивают декорированную функцию и возвращают обёртку. Если функция-обёртка не обновляется, метаданные возвращаемой функции будут отражать определение обёртки, а не исходной функции, что обычно не очень полезно.

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

Это удобная функция для вызова [`update_wrapper()`](https://python-all.ru/2.7/library/functools.html#functools.update_wrapper) в качестве декоратора функции при определении функции-обёртки. Она эквивалентна `partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)`. Например:

```python
>>> 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`](https://python-all.ru/2.7/library/functools.html#functools.partial) Объекты

Объекты [`partial`](https://python-all.ru/2.7/library/functools.html#functools.partial) – это вызываемые объекты, создаваемые [`partial()`](https://python-all.ru/2.7/library/functools.html#functools.partial). Они имеют три атрибута только для чтения:

#### `partial.func`

Вызываемый объект или функция. Вызовы объекта [`partial`](https://python-all.ru/2.7/library/functools.html#functools.partial) будут перенаправлены в [`func`](https://python-all.ru/2.7/library/functools.html#functools.partial.func) с новыми аргументами и ключевыми словами.

#### `partial.args`

Крайние левые позиционные аргументы, которые будут добавлены перед позиционными аргументами, переданными при вызове объекта [`partial`](https://python-all.ru/2.7/library/functools.html#functools.partial).

#### `partial.keywords`

Ключевые аргументы, которые будут предоставлены при вызове объекта [`partial`](https://python-all.ru/2.7/library/functools.html#functools.partial).

Объекты [`partial`](https://python-all.ru/2.7/library/functools.html#functools.partial) похожи на объекты `function` тем, что они вызываемы, могут быть слабыми ссылками и могут иметь атрибуты. Есть несколько важных отличий. Например, атрибуты [`__name__`](https://python-all.ru/2.7/library/stdtypes.html#definition.__name__) и `__doc__` не создаются автоматически. Кроме того, объекты [`partial`](https://python-all.ru/2.7/library/functools.html#functools.partial), определённые в классах, ведут себя как статические методы и не превращаются в связанные методы при поиске атрибута экземпляра.
