Функция как аргумент: ключевой приём Python
В Python функция может выступать в качестве аргумента другой функции. Этот механизм лежит в основе функционального программирования и позволяет строить гибкий, переиспользуемый код. В статье рассматриваются различные способы применения такого подхода.
Основные способы передачи функции как аргумента
Наиболее распространённое и эффективное решение - использование встроенных функций, таких как sorted, map, filter, которые принимают функцию в качестве аргумента. Например, сортировка списка по длине строк:
words = ['яблоко', 'груша', 'слива', 'апельсин']
sorted_words = sorted(words, key=len)
print(sorted_words)аргументы print python (аргументы функции print в python)
['груша', 'слива', 'яблоко', 'апельсин']
Python 3 аргументы (аргументы в python 3)
Этот подход прост, читаем и опирается на оптимизированный код CPython. Цель - применить функцию к каждому элементу или использовать результат для сравнения.
Как применить произвольную функцию к каждому элементу последовательности?
Используется map. Функция применяется к каждому элементу и возвращается итератор.
def square(x):
return x * x
numbers = [1, 2, 3, 4]
result = list(map(square, numbers))
print(result)
аргумент параметр python (аргументы и параметры в python)
[1, 4, 9, 16]
аргумент класса python (аргументы класса python)
Как отфильтровать элементы по условию?
Применяется filter. Он передаёт каждый элемент функции, которая возвращает True/False.
def is_even(x):
return x % 2 == 0
evens = list(filter(is_even, range(10)))
print(evens)Python аргументы строки (аргументы строки в python (командная строка))
[0, 2, 4, 6, 8]
аргумент метода python (аргументы метода python)
Как создать собственную функцию высшего порядка?
Определяется функция, которая принимает другую функцию и вызывает её внутри себя.
def apply_twice(func, value):
return func(func(value))
def add_one(x):
return x + 1
print(apply_twice(add_one, 5))Python args (аргументы в python)
7
именованные аргументы функции python (именованные аргументы функции python)
Цель такого подхода - абстрагирование повторяющегося шаблона вызова.
Как использовать функцию обратного вызова (callback)?
Callback передаётся для выполнения после завершения операции. Например, при обработке событий.
def on_complete(message):
print(f'Готово: {message}')
def process(data, callback):
result = data.upper()
callback(result)
process('hello', on_complete)именованные аргументы python (именованные аргументы python)
Готово: HELLO
Частые ошибки при передаче функции как аргумента:
- Передача результата вызова вместо ссылки: если написать sorted(words, key=len()) вместо key=len, то вызовется len() без аргумента и произойдёт ошибка. Нужно передавать саму функцию, не вызывая её.
- Несоответствие сигнатуры: если ожидается функция одного аргумента, а передаётся функция, принимающая два, возникнет исключение. Следует использовать lambda или partial.
- Мутабельные аргументы: если переданная функция изменяет входной объект, это может привести к побочным эффектам. Нужно создавать копии данных внутри функции.
Продвинутые примеры с функциями в качестве аргументов
Ниже представлены примеры, выходящие за рамки повседневного использования, но демонстрирующие мощь подхода.
Передача нескольких функций и композиция
def compose(f, g):
return lambda x: f(g(x))
def double(x):
return x * 2
def increment(x):
return x + 1
double_then_increment = compose(increment, double)
print(double_then_increment(5))11
Использование functools.partial для фиксации аргументов
from functools import partial
def power(base, exponent):
return base ** exponent
square = partial(power, exponent=2)
cube = partial(power, exponent=3)
print(square(5))
print(cube(5))25 125
Функция с замыканием в качестве аргумента
def make_multiplier(n):
def multiplier(x):
return x * n
return multiplier
def apply_to_list(func, lst):
return [func(x) for x in lst]
times3 = make_multiplier(3)
print(apply_to_list(times3, [1, 2, 3]))[3, 6, 9]
Реализация паттерна "Стратегия" через передачу функции
def bubble_sort(arr, compare):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if compare(arr[j], arr[j+1]) > 0:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
asc = lambda a,b: a - b
desc = lambda a,b: b - a
data = [3, 1, 4, 1, 5]
print(bubble_sort(data[:], asc))
print(bubble_sort(data[:], desc))[1, 1, 3, 4, 5] [5, 4, 3, 1, 1]
Декоратор с параметром (функция, возвращающая декоратор)
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def greet(name):
print(f'Привет, {name}')
greet('Мир')Привет, Мир Привет, Мир Привет, Мир