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

---

# 9.8. `functools` – Функции высшего порядка и операции с вызываемыми объектами

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

Модуль `functools` определяет следующие функции:

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

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

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

Это удобная функция для вызова `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/3.1/library/functools.html#functools.partial) Объекты

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

#### `partial.func`

Вызываемый объект или функция. Вызовы объекта

[`partial`](https://python-all.ru/3.1/library/functools.html#functools.partial)

будут перенаправлены к

[`func`](https://python-all.ru/3.1/library/functools.html#functools.partial.func)

с новыми аргументами и ключевыми словами.

#### `partial.args`

Крайние слева позиционные аргументы, которые будут добавлены в начало позиционных аргументов, передаваемых при вызове объекта

[`partial`](https://python-all.ru/3.1/library/functools.html#functools.partial)

.

#### `partial.keywords`

Ключевые аргументы, которые будут предоставлены, когда объект

[`partial`](https://python-all.ru/3.1/library/functools.html#functools.partial)

будет вызван.

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