0Pricing
Python Academy · Урок

functools: partial и reduce

Создавайте специализированные функции с partial и сворачивайте последовательности с помощью reduce.

«functools: partial и reduce» — бесплатный урок Python Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

Обзор functools

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

import functools

# partial, reduce, lru_cache, wraps, cached_property ...
print(dir(functools))

partial()

functools.partial(func, *args, **kw) создаёт новый вызываемый объект с заранее заданными некоторыми аргументами.

import functools

def power(base, exp):
    return base ** exp

square = functools.partial(power, exp=2)
cube   = functools.partial(power, exp=3)

print(square(4))  # 16
print(cube(3))    # 27

partial для методов

Используйте partial, чтобы адаптировать методы с фиксированными параметрами для применения в качестве функций обратного вызова или обработчиков событий.

import functools, logging

logger = logging.getLogger("app")
log_error = functools.partial(logger.log, logging.ERROR)

log_error("Something went wrong")

partial и lambda

Для предварительного заполнения аргументов предпочтительнее использовать partial, а не lambda, поскольку этот объект можно сериализовать с помощью pickle, он имеет информативное строковое представление и сохраняет строку документации.

import functools

mul = lambda x, y: x * y

double_lambda = lambda x: mul(x, 2)            # lambda approach
double_partial = functools.partial(mul, y=2)   # partial approach

print(double_partial(5))   # 10

reduce()

functools.reduce(func, iterable, initial) сворачивает итерируемый объект слева направо с помощью бинарной функции.

import functools, operator

total = functools.reduce(operator.add, [1,2,3,4,5])
print(total)   # 15

product = functools.reduce(operator.mul, [1,2,3,4,5], 1)
print(product) # 120

Создание max() с помощью reduce

Продемонстрируйте принцип работы reduce, заново реализовав max():

import functools

def my_max(seq):
    return functools.reduce(lambda a, b: a if a > b else b, seq)

print(my_max([3, 1, 4, 1, 5, 9]))  # 9

Выравнивание вложенных списков

Используйте reduce вместе с operator.iconcat, чтобы убрать один уровень вложенности.

import functools, operator

nested = [[1,2],[3,4],[5]]
flat = functools.reduce(operator.iconcat, nested, [])
print(flat)  # [1, 2, 3, 4, 5]

Создание URL с помощью partial

Практический шаблон с partial: зафиксируйте базовый URL и создайте специализированные вспомогательные функции для запросов.

import functools, urllib.request

def fetch(base, path):
    url = base.rstrip("/") + "/" + path.lstrip("/")
    with urllib.request.urlopen(url) as r:
        return r.read()

github = functools.partial(fetch, "https://api.github.com")
# github("/users/octocat")

wraps(): сохранение метаданных

При написании декораторов используйте @functools.wraps(wrapped), чтобы обёртка сохраняла имя и строку документации исходной функции.

import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        return func(*args, **kw)
    return wrapper

@decorator
def greet(name):
    """Say hello."""
    return f"Hello, {name}"

print(greet.__name__)  # greet
print(greet.__doc__)   # Say hello.

total_ordering

@functools.total_ordering заполняет отсутствующие методы сравнения, если Вы определили __eq__ и один из методов __lt__/__le__/__gt__/__ge__.

import functools

@functools.total_ordering
class Version:
    def __init__(self, major, minor):
        self.v = (major, minor)
    def __eq__(self, o): return self.v == o.v
    def __lt__(self, o): return self.v < o.v

print(Version(1,2) >= Version(1,1))  # True

singledispatch

@functools.singledispatch создаёт функцию, которая выбирает разные реализации в зависимости от типа первого аргумента.

import functools

@functools.singledispatch
def process(arg):
    raise NotImplementedError(type(arg))

@process.register(int)
def _(n): return n * 2

@process.register(str)
def _(s): return s.upper()

print(process(5))     # 10
print(process("hi"))  # HI

Быстрая проверка

Что создаёт functools.partial(pow, 2)?

Итоги

partial заранее задаёт аргументы функции; reduce сворачивает последовательность с помощью бинарной функции; wraps сохраняет метаданные декоратора; total_ordering заполняет методы сравнения; singledispatch выбирает реализацию по типу.

Часто задаваемые вопросы

Урок «functools: partial и reduce» бесплатный?

Да — полный текст урока «functools: partial и reduce» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «functools: partial и reduce»?

Создавайте специализированные функции с partial и сворачивайте последовательности с помощью reduce. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «functools: partial и reduce»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. itertools: бесконечные и конечные итераторы
  2. itertools: комбинаторика
  3. functools: partial и reduce
  4. functools: lru_cache и cached_property
← Назад к Python Academy