← Назад к вопросам

Приведи пример использования функции в Python

2.0 Middle🔥 131 комментариев
#Python Core#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Приведи пример использования функции в Python

Это вопрос о функциях как объектов первого класса (first-class objects) и их практическом применении. Функции в Python — это мощный инструмент, который можно передавать, возвращать и комбинировать.

Базовый пример: функция как объект

# Функция — это объект, как и всё в Python
def greet(name):
    return f"Hello, {name}!"

# Можно присвоить переменной
say_hello = greet  # Не вызов, а присваивание функции
print(say_hello("Alice"))  # Hello, Alice!

# Получить информацию о функции
print(type(greet))  # <class 'function'>
print(greet.__name__)  # 'greet'
print(greet.__doc__)  # None (потому что нет docstring)

Практический пример 1: Higher-Order Functions

# Функция, которая принимает другую функцию
def apply_operation(operation, x, y):
    """Применяет операцию к двум числам."""
    return operation(x, y)

def add(a, b):
    return a + b

def multiply(a, b):
    return a * b

# Передаём функцию как аргумент
result1 = apply_operation(add, 5, 3)  # 8
result2 = apply_operation(multiply, 5, 3)  # 15

print(result1)  # 8
print(result2)  # 15

Это Strategy pattern — выбор алгоритма во время выполнения.

Практический пример 2: Возвращение функции

# Функция, которая ВОЗВРАЩАЕТ другую функцию
def create_multiplier(factor):
    """Создаёт функцию умножения на конкретное число."""
    def multiplier(x):
        return x * factor
    return multiplier  # Возвращаем функцию!

# Используем
triple = create_multiplier(3)
double = create_multiplier(2)

print(triple(10))  # 30
print(double(10))  # 20

# Каждая функция помнит свой 'factor' (closure)
print(triple.__closure__[0].cell_contents)  # 3
print(double.__closure__[0].cell_contents)  # 2

Это closure — функция с захватом переменной.

Практический пример 3: Декораторы

import time
from functools import wraps

# Декоратор — это функция, которая модифицирует другую функцию
def timing_decorator(func):
    @wraps(func)  # Сохраняет __name__ и __doc__
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)  # Вызов оригинальной функции
        end = time.time()
        print(f"{func.__name__} took {end - start:.4f} seconds")
        return result
    return wrapper

# Применяем декоратор
@timing_decorator
def slow_function():
    time.sleep(1)
    return "Done!"

result = slow_function()
# Output: slow_function took 1.0005 seconds
# Done!

Декораторы используются всюду: Flask @app.route(), Django @login_required, pytest @patch.

Практический пример 4: Map, Filter, Sorted с функциями

# Python предоставляет функции высшего порядка для работы с коллекциями

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# map() — применить функцию ко всем элементам
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # [1, 4, 9, 16, 25, 36, 49, 64, 81]

# filter() — оставить элементы, где функция вернула True
even = list(filter(lambda x: x % 2 == 0, numbers))
print(even)  # [2, 4, 6, 8]

# sorted() с key функцией
words = ["apple", "zoo", "banana", "cat"]
sorted_by_length = sorted(words, key=len)
print(sorted_by_length)  # ['zoo', 'cat', 'apple', 'banana']

# sorted с кастомной функцией
def sort_key(word):
    return len(word), word  # Сначала по длине, потом по алфавиту

complex_sorted = sorted(words, key=sort_key)
print(complex_sorted)  # ['cat', 'zoo', 'apple', 'banana']

Практический пример 5: Callback функции

# В асинхронном коде функции используются как callbacks

import asyncio

# Функция, которая выполняет асинхронную работу
async def fetch_data(url, callback):
    """Получает данные и передаёт результат callback функции."""
    # Имитируем async операцию
    await asyncio.sleep(1)
    data = {"url": url, "status": 200, "data": "Response"}
    # Вызываем callback с результатом
    callback(data)

# Callback функция
def process_response(data):
    print(f"Received: {data['data']} from {data['url']}")

# Использование
async def main():
    await fetch_data("https://api.example.com", process_response)

asyncio.run(main())
# Output: Received: Response from https://api.example.com

Практический пример 6: Compositon функций

# Комбинирование функций — функциональное программирование

def compose(f, g):
    """Возвращает композицию f(g(x))."""
    def composed(x):
        return f(g(x))
    return composed

# Создаём новую функцию из двух
def add_one(x):
    return x + 1

def double(x):
    return x * 2

# Комбинируем: (x + 1) * 2
add_then_double = compose(double, add_one)
print(add_then_double(5))  # (5 + 1) * 2 = 12

# Или в обратном порядке: 2 * x + 1
double_then_add = compose(add_one, double)
print(double_then_add(5))  # (5 * 2) + 1 = 11

Практический пример 7: Default параметр функции

# ❌ ОПАСНО — mutable default argument
def add_to_list_bad(item, items=[]):
    items.append(item)
    return items

list1 = add_to_list_bad(1)  # [1]
list2 = add_to_list_bad(2)  # [1, 2] — НЕПРАВИЛЬНО!

# ✅ ПРАВИЛЬНО — использовать None
def add_to_list_good(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

list1 = add_to_list_good(1)  # [1]
list2 = add_to_list_good(2)  # [2] — ПРАВИЛЬНО

Практический пример 8: *args и **kwargs

# Функции, которые принимают переменное количество аргументов

def print_all(*args, **kwargs):
    """*args — кортеж позиционных аргументов, **kwargs — словарь именованных."""
    print("Positional:", args)
    print("Named:", kwargs)

print_all(1, 2, 3, name="Alice", age=30)
# Output:
# Positional: (1, 2, 3)
# Named: {'name': 'Alice', 'age': 30}

# Практический пример — логирование
def log_with_context(*args, level="INFO", **context):
    message = " ".join(str(arg) for arg in args)
    print(f"[{level}] {message} | context: {context}")

log_with_context("User", "logged in", user_id=123, ip="192.168.1.1")
# Output: [INFO] User logged in | context: {'user_id': 123, 'ip': '192.168.1.1'}

Практический пример 9: functools.reduce

from functools import reduce
from operator import mul

# Reduce применяет функцию кумулятивно
numbers = [1, 2, 3, 4, 5]

# Сумма всех чисел
total = reduce(lambda a, b: a + b, numbers)
print(total)  # 15

# Факториал
factorial = reduce(mul, range(1, 6))  # 1 * 2 * 3 * 4 * 5
print(factorial)  # 120

# Построение словаря из списка пар
pairs = [("a", 1), ("b", 2), ("c", 3)]
result = reduce(lambda d, pair: {**d, pair[0]: pair[1]}, pairs, {})
print(result)  # {'a': 1, 'b': 2, 'c': 3}

Практический пример 10: Регистрирование функций

# Реальный пример из фреймворков типа Flask

class EventBus:
    def __init__(self):
        self.handlers = {}
    
    def on(self, event_name):
        """Декоратор для регистрирования обработчика события."""
        def decorator(func):
            if event_name not in self.handlers:
                self.handlers[event_name] = []
            self.handlers[event_name].append(func)
            return func
        return decorator
    
    def emit(self, event_name, data):
        """Вызвать все обработчики события."""
        if event_name in self.handlers:
            for handler in self.handlers[event_name]:
                handler(data)

# Использование
bus = EventBus()

@bus.on("user_login")
def log_login(data):
    print(f"User {data['username']} logged in")

@bus.on("user_login")
def send_notification(data):
    print(f"Sending notification to {data['email']}")

# Вызов
bus.emit("user_login", {"username": "alice", "email": "alice@example.com"})
# Output:
# User alice logged in
# Sending notification to alice@example.com

Вывод

Функции в Python — это:

  • First-class objects — можно передавать, возвращать, сохранять
  • Основа функционального программирования — map, filter, reduce, compose
  • Ключ к декораторам — модификация поведения функций
  • Callback механизм — асинхронное программирование
  • Strategy pattern — выбор алгоритма во время выполнения

Это одна из самых мощных особенностей Python, которая делает его гибким и выразительным языком.