Ответ
Модуль functools — это часть стандартной библиотеки Python, предоставляющая высокоуровневые функции для работы с другими функциями или вызываемыми объектами. Он используется для функционального программирования, оптимизации и упрощения кода.
Основные функции и их применение:
@lru_cache(maxsize=128): Декоратор для мемоизации (кэширования) результатов функции. Ускоряет повторные вызовы функций с одинаковыми аргументами, особенно полезен для рекурсивных функций или дорогих вычислений.functools.partial(func, *args, **kwargs): Создаёт новую функцию с частично применёнными аргументами. Позволяет "зафиксировать" некоторые аргументы исходной функции, упрощая её использование в контекстах, где требуется функция с меньшим числом параметров (например, в колбэках).@functools.wraps(wrapped): Декоратор, используемый при создании других декораторов. Он копирует имя, docstring, модуль и другие метаданные оборачиваемой функции в функцию-обёртку, что улучшает отладку и интроспекцию.functools.reduce(function, iterable[, initializer]): Применяет функцию к элементам последовательности, сводя её к единственному значению. (В Python 3 перенесён из встроенных функций вfunctools).
Пример использования @lru_cache:
from functools import lru_cache
@lru_cache(maxsize=None) # maxsize=None означает неограниченный кэш
def fibonacci(n: int) -> int:
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# Без кэша вычисление fibonacci(30) было бы значительно медленнее
print(fibonacci(30))
Пример использования functools.partial:
from functools import partial
def power(base: int, exponent: int) -> int:
return base ** exponent
# Создаём новую функцию, которая возводит число в квадрат
square = partial(power, exponent=2)
print(square(5)) # Выведет 25 (5^2)
# Создаём функцию, которая возводит 2 в степень
power_of_two = partial(power, base=2)
print(power_of_two(3)) # Выведет 8 (2^3) Ответ 18+ 🔞
А, functools, говоришь? Ну это ж, блядь, такая штука в Питоне, которая как будто бы взяла все эти ваши умные книжки по функциональщине, переварила их и выплюнула в виде готовых инструментов, чтобы ты не изобретал велосипед с квадратными колёсами. Короче, библиотека для ленивых гениев, чтобы код был короче, а мозг — целее.
Чем там можно разжиться, если покопаться:
@lru_cache(maxsize=128): Это, сука, волшебный пендель для твоих тормозных функций. Вешаешь этот декоратор на какую-нибудь рекурсивную поеботу вроде вычисления факториала или чисел Фибоначчи, и она перестаёт считать одно и то же по сто раз. Она просто запоминает, что вот для аргумента5ответ был120, и в следующий раз не лезет в дебри, а сразу плюёт тебе результат. Максимально полезная хуйня, ебать мои старые костыли.- *`functools.partial(func, args, kwargs)`: Представь, у тебя есть функция с кучей параметров, а тебе надо её впихнуть куда-то, где ждут функцию с одним аргументом. Вот
partial— это как зажим для патронов. Ты говоришь: «Вот эта функция, но давай второй аргумент у неё всегда будет равен двойке». И получаешь новую, урезанную функцию, которая уже готова к бою. Удобно, как хуй с пальто. @functools.wraps(wrapped): Это для параноиков и педантов. Когда ты пишешь свой собственный декоратор и оборачиваешь им другую функцию, то обёрнутая функция теряет своё имя и описание. Весь мир начинает думать, что её зовутwrapper, а неsuper_calc. Так вотwrapsвозвращает украденные документы и имя на место, чтобы при отладке не охуевать, глядя в стектрейс.functools.reduce(function, iterable[, initializer]): Старый добрый агрегатор. Берет последовательность и склеивает её в одно значение, применяя функцию попарно. Типа «вот тебе список чисел, а ты просуммируй их». В Питоне 3 её, хитрая жопа, вынесли из встроенных функций сюда, вfunctools, чтобы народ меньше путался.
Вот смотри, как @lru_cache делает из черепахи гепарда:
from functools import lru_cache
@lru_cache(maxsize=None) # maxsize=None — это типа «кэшируй всё, нахуй»
def fibonacci(n: int) -> int:
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# Без этого декоратора вычисление fibonacci(40) заставило бы тебя сходить за кофе, покурить и вернуться.
# А так — чирик, и готово.
print(fibonacci(30))
А вот partial в деле, чтобы не писать одно и то же:
from functools import partial
def power(base: int, exponent: int) -> int:
return base ** exponent
# Делаем из пушки по воробьям — специализированный дробовик.
# «Возвести в квадрат» — это же просто «power, но exponent=2».
square = partial(power, exponent=2)
print(square(5)) # Напечатает 25 (5 в квадрате, ёпта)
# А это — «power, но base=2». Получаем функцию «двойка в степень».
power_of_two = partial(power, base=2)
print(power_of_two(3)) # Напечатает 8 (2 в кубе, если кто не в курсе)
Вот и весь сказ. Библиотека не огромная, но каждая функция в ней — как отвёртка в правильном наборе инструментов: вроде простая, но когда надо — другой хуйней не заменишь.