7. Функции

Объявление функций
Заголовок раздела «Объявление функций»# Базовый синтаксисdef greet(name: str) -> str: """Возвращает приветствие.""" return f"Hello, {name}!"
result = greet("Яша") # "Hello, Яша!"Параметры функций
Заголовок раздела «Параметры функций»Python очень гибкий в работе с параметрами:
# Обязательные параметрыdef add(a: int, b: int) -> int: return a + b
# Параметры по умолчаниюdef greet(name: str, greeting: str = "Hello") -> str: return f"{greeting}, {name}!"
greet("Яша") # "Hello, Яша!"greet("Яша", "Привет") # "Привет, Яша!"
# Именованные аргументы (keyword arguments)def create_user(name: str, age: int, role: str = "user"): return {"name": name, "age": age, "role": role}
# Вызов с именованными аргументами (порядок не важен!)user = create_user(age=25, name="Яша", role="admin")
# *args — произвольное количество позиционных аргументовdef sum_all(*args: int) -> int: return sum(args)
sum_all(1, 2, 3, 4, 5) # 15
# **kwargs — произвольное количество именованных аргументовdef create_profile(**kwargs) -> dict: return kwargs
create_profile(name="Яша", age=2, city="Москва")# {"name": "Яша", "age": 2, "city": "Москва"}
# Всё вместеdef mixed(required, *args, default="нет", **kwargs): print(f"required: {required}") print(f"args: {args}") print(f"default: {default}") print(f"kwargs: {kwargs}")Аннотации типов (Type Hints)
Заголовок раздела «Аннотации типов (Type Hints)»from typing import Optional, Union, Any
# Optional — значение или Nonedef find_user(id: int) -> Optional[dict]: # может вернуть dict или None ...
# Union — один из типовdef process(value: Union[int, str]) -> str: return str(value)
# Python 3.10+: используй | вместо Uniondef process(value: int | str) -> str: return str(value)
# Коллекцииdef get_names(users: list[dict]) -> list[str]: return [u["name"] for u in users]
def get_config() -> dict[str, Any]: return {"debug": True, "port": 8000}Lambda функции
Заголовок раздела «Lambda функции»# lambda: маленькие анонимные функцииsquare = lambda x: x ** 2add = lambda a, b: a + b
# Основное использование — в качестве аргументаusers = [ {"name": "Вера", "age": 30}, {"name": "Анна", "age": 25}, {"name": "Гена", "age": 22},]
# Сортировка по возрастуsorted_users = sorted(users, key=lambda u: u["age"])
# Сортировка по имени, по убываниюsorted_by_name_desc = sorted(users, key=lambda u: u["name"], reverse=True)
# filter, map, reducenumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))# [2, 4, 6, 8, 10]
doubled = list(map(lambda x: x * 2, numbers))# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# Но comprehensions читаемее!evens = [x for x in numbers if x % 2 == 0]doubled = [x * 2 for x in numbers]Декораторы
Заголовок раздела «Декораторы»Декораторы — функции, которые оборачивают другие функции. Широко используются в FastAPI и Django!
# Простой декораторdef log_call(func): def wrapper(*args, **kwargs): print(f"Вызов: {func.__name__}") result = func(*args, **kwargs) print(f"Результат: {result}") return result return wrapper
@log_calldef add(a, b): return a + b
add(2, 3)# Вызов: add# Результат: 5
# Декоратор с параметрамиdef repeat(n: int): def decorator(func): def wrapper(*args, **kwargs): for _ in range(n): result = func(*args, **kwargs) return result return wrapper return decorator
@repeat(3)def hello(name: str): print(f"Hello, {name}!")
hello("Яша") # Выведет 3 раза
# functools.wraps — сохраняет метаданные функцииfrom functools import wraps
def timer(func): import time @wraps(func) # важно! def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.__name__} выполнялась {end - start:.3f}с") return result return wrapper
@timerdef slow_function(): import time time.sleep(1) return "готово"Closures (замыкания)
Заголовок раздела «Closures (замыкания)»def make_counter(start: int = 0): count = start
def increment(step: int = 1): nonlocal count # обращение к внешней переменной count += step return count
return increment
counter = make_counter(10)counter() # 11counter() # 12counter(5) # 17
# Практический пример: фабрика функцийdef make_multiplier(factor: int): return lambda x: x * factor
double = make_multiplier(2)triple = make_multiplier(3)
double(5) # 10triple(5) # 15Генераторы
Заголовок раздела «Генераторы»# Генератор — функция с yield, возвращает значения ленивоdef fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
fib = fibonacci()for _ in range(10): print(next(fib)) # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
# Генераторное выражение (как list comprehension, но ленивое)big_sum = sum(x**2 for x in range(1_000_000)) # не хранит всё в памяти
# Практический пример: чтение большого файлаdef read_chunks(filename: str, chunk_size: int = 1024): with open(filename) as f: while chunk := f.read(chunk_size): yield chunkПрактические примеры
Заголовок раздела «Практические примеры»# Утилиты для работы с даннымиfrom typing import TypeVar, Callable, Iterable
T = TypeVar("T")
def first(items: Iterable[T], predicate: Callable[[T], bool]) -> T | None: """Найти первый элемент, удовлетворяющий условию.""" return next((item for item in items if predicate(item)), None)
users = [{"name": "Анна", "role": "admin"}, {"name": "Борис", "role": "user"}]admin = first(users, lambda u: u["role"] == "admin")# {"name": "Анна", "role": "admin"}
def group_by(items: list[T], key: Callable[[T], str]) -> dict[str, list[T]]: """Сгруппировать элементы по ключу.""" result: dict[str, list[T]] = {} for item in items: k = key(item) result.setdefault(k, []).append(item) return result
by_role = group_by(users, lambda u: u["role"])# {"admin": [{"name": "Анна", ...}], "user": [{"name": "Борис", ...}]}Задание
Заголовок раздела «Задание»# Задание 1: Декоратор кэширования# Напиши декоратор @cache, который сохраняет результаты функции# и при повторном вызове с теми же аргументами возвращает из кэша
# Задание 2: Функция пагинацииdef paginate(items: list, page: int, page_size: int) -> dict: """ Возвращает страницу данных. Returns: {"items": [...], "total": int, "page": int, "pages": int} """ pass # реализуй!
# Задание 3: Генератор уникальных IDdef id_generator(prefix: str = "id"): """Бесконечный генератор уникальных ID: id-1, id-2, id-3, ...""" pass # реализуй!В следующем уроке — списки, словари и кортежи в деталях!