functools.partial: частично применённые функции
Одной из самых мощных и часто используемых функций в библиотеке functools является functools.partial. Она позволяет создавать новые функции, фиксируя некоторые аргументы исходной функции. Это полезно для упрощения вызовов функций с большим числом параметров или для создания специализированных версий функций.
functools.partial - создает новую функцию с заранее предустановленными значениями для одного или нескольких аргументов исходной функции. Проще говоря, это способ "зафиксировать" некоторые аргументы функции, чтобы не нужно было указывать их каждый раз при вызове.
Синтаксис
functools.partial(func, /, *args, **kwargs)
- func: исходная функция, к которой будет применена частичная фиксация аргументов
- *args: позиционные аргументы, которые нужно зафиксировать
- **kwargs: именованные аргументы, которые нужно зафиксировать
Рассмотрим простую функцию, которая принимает три аргумента и возвращает их сумму:
def add(a, b, c): return a + b + c
Создадим новую функцию, фиксируя первый аргумент:
import functools add_five = functools.partial(add, 5)
Теперь add_five – это функция, которая ожидает два оставшихся аргумента:
print(add_five(10, 15)) # Вывод: 30 (5 + 10 + 15)
Рассмотрим более практичный пример использования functools.partial. Допустим, у нас есть функция для обработки строк:
def format_string(template, *args, **kwargs): return template.format(*args, **kwargs)
Эта функция позволяет форматировать строки с помощью шаблонов. Создадим частично примененную функцию для часто используемого нами шаблона email-письма:
email_template = "Dear {name},\n\nThank you for your interest in {product}. We are pleased to offer you a special discount on your next purchase." format_email = functools.partial(format_string, email_template)
Теперь можно легко создавать персонализированные письма:
print(format_email(name="John Doe", product="Pyplanet Programming Course"))
Частичные функции и методы
functools.partial также удобна для использования с методами классов. Рассмотрим следующий пример:
class Calculator: def __init__(self, factor): self.factor = factor def multiply(self, x, y): return x * y * self.factor calc = Calculator(10) partial_multiply = functools.partial(calc.multiply, 5)
Здесь partial_multiply фиксирует аргумент x метода multiply класса Calculator:
print(partial_multiply(4)) # Вывод: 200 (5 * 4 * 10)
Удобство работы с библиотеками
Многие библиотеки в Python, такие как multiprocessing и concurrent.futures, требуют функции с определенным интерфейсом (например, функции, принимающие один аргумент). functools.partial позволяет легко адаптировать функции к этим требованиям.
Пример с использованием multiprocessing map:
from multiprocessing import Pool def power(base, exponent): return base ** exponent power_of_two = functools.partial(power, 2) with Pool(5) as p: results = p.map(power_of_two, [1, 2, 3, 4, 5]) print(results) # Вывод: [2, 4, 8, 16, 32]