Ответ
Python не является чисто функциональным языком, но включает в себя множество элементов из этой парадигмы, позволяя писать код в функциональном стиле.
Основные элементы:
-
Функции как объекты первого класса: Функции можно присваивать переменным, передавать в качестве аргументов и возвращать из других функций.
-
Функции высшего порядка: Функции, которые принимают другие функции в качестве аргументов или возвращают их. Классические примеры:
map(),filter(),reduce().numbers = [1, 2, 3, 4] # map применяет лямбда-функцию к каждому элементу squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9, 16] -
Лямбда-функции: Анонимные однострочные функции, создаваемые с помощью ключевого слова
lambda.add = lambda a, b: a + b print(add(5, 3)) # 8 -
Замыкания (Closures): Внутренние функции, которые «помнят» и имеют доступ к переменным из локальной области видимости внешней функции, даже после того как внешняя функция завершила свое выполнение.
def outer_func(msg): def inner_func(): print(msg) return inner_func printer = outer_func("Hello, World!") printer() # Выведет "Hello, World!" -
Иммутабельные типы данных: Встроенные типы, такие как
tuple,frozenset,str, чьи значения нельзя изменить после создания. Это ключевая концепция ФП для избежания побочных эффектов. -
Генераторы и ленивые вычисления: Генераторы, создаваемые с помощью
yield, вычисляют значения по мере необходимости, что экономит память и повышает производительность. -
Модуль
functools: Содержит утилиты для работы с функциями, такие какpartialдля частичного применения функций,reduceдля свертки последовательностей иlru_cacheдля мемоизации.
Ответ 18+ 🔞
Слушай, а вот Python, он вроде как не монах в храме функционального программирования, но, блядь, тащит туда кучу фишек, как будто на халяву в бар приперся. Можно писать почти как на Haskell, только без этих, блядь, мозговыносящих монад на каждом шагу.
Чем он там прикалывается:
-
Функции — это как печеньки в кармане. Их можно сувать куда угодно: в переменные, в аргументы, возвращать из других функций. Полный беспредел, но удобно, ёпта.
def кричать(текст): return текст.upper() + "!!!" гребаный_мегафон = кричать # Смотри-ка, функция в переменной! print(гребаний_мегафон("тише")) # ТИШЕ!!! -
Функции высшего порядка — это такие шеф-повара, которые готовят, используя других поваров (другие функции). Классика жанра —
map,filter,reduce.reduce, правда, спрятали, как краденый велосипед, в модульfunctools.числа = [1, 2, 3, 4] # map — как конвейер: берет функцию и применяет ко всему подряд в_квадрате = list(map(lambda x: x**2, числа)) # [1, 4, 9, 16] # filter — как сито: оставляет только то, что проходет проверку чётные = list(filter(lambda x: x % 2 == 0, числа)) # [2, 4] -
Лямбда-функции — это одноразовые зажигалки. Создал, чиркнул, выкинул. Анонимные и в одну строчку. Для сложной логики — иди нахуй, пиши нормальную функцию.
прибавить = lambda a, b: a + b print(прибавить(5, 3)) # 8 # Чаще их используют прямо в месте, где нужны, как вот выше в map. -
Замыкания — это функции с памятью, как слон. Внутренняя функция помнит всё, что было во внешней, даже когда та уже давно сдохла. Прямо мистика какая-то, блядь.
def создать_приветилку(имя): # Внутренняя функция запекает в себе 'имя' def приветилка(): return f"Ну здарова, {имя}, ёпта!" return приветилка позвать_васька = создать_приветилку("Васьок") print(позвать_васька()) # Ну здарова, Васьок, ёпта! # 'Васьок' уже давно в ином измерении, а функция его помнит. Жуть. -
Неизменяемые типы — священные коровы. Кортежи (
tuple), строки (str), замороженные множества (frozenset). Создал — и хоть тресни, не изменишь. Это чтобы твой код не превращался в свалку непредсказуемых побочных эффектов, где всё плывёт и меняется, как сознание алкаша. -
Генераторы — это ленивые жопы. Они не делают всю работу сразу, а выдают результат по одному, когда их пнёшь. Экономия памяти — овердохуища, особенно когда данных много.
def бесконечная_лента_чисел(старт): i = старт while True: yield i # yield — это волшебное слово "на, держи один, остальные потом" i += 1 ленивец = бесконечная_лента_чисел(10) print(next(ленивец)) # 10 print(next(ленивец)) # 11 # И так до скончания времён, не жрёт память. -
Модуль
functools— это ящик с продвинутым инструментом. Тут тебе иpartial(чтобы зафиксировать функции часть аргументов заранее, как приклеить), иreduce(для сворачивания последовательностей в одно значение), иlru_cache(чтобы функция запоминала результаты своих вызовов и не пересчитывала одно и то же по сто раз — умно, блядь).
Короче, Python даёт тебе в руки функциональные фишки, но не заставляет ими пользоваться. Хочешь — пиши в чистом стиле, хочешь — мешай с императивным кодом. Главное — не устраивай пиздец в проекте.