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

Как использовать типизированные аргументы функции?

2.0 Middle🔥 111 комментариев
#Python Core

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

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

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

Использование типизированных аргументов функции в Python

Типизация аргументов функции (type hints) — это одна из ключевых возможностей Python для повышения читаемости, безопасности и удобства разработки. Она позволяет явно указать, какие типы данных должны принимать функции.

1. Базовая типизация

def greet(name: str, age: int) -> str:
    """Типизированная функция с аннотацией типов."""
    return f"Привет, {name}! Тебе {age} лет."

# Корректное использование
result = greet("Иван", 30)
print(result)  # Привет, Иван! Тебе 30 лет.

# IDE предупредит, но код всё ещё выполнится
result = greet("Иван", "30")  # Несоответствие типа

Типизация в Python не принудительна (это не Java), но помогает:

  • IDE выявлять ошибки
  • Читать и понимать код
  • Документировать ожидаемые типы
  • Использовать инструменты статического анализа (mypy, pyright)

2. Встроенные типы

def process_data(
    name: str,
    count: int,
    price: float,
    is_active: bool,
    items: list,
    config: dict
) -> None:
    """Функция с различными встроенными типами."""
    print(f"{name}: {count} шт. по {price} руб.")
    print(f"Активно: {is_active}")
    print(f"Товары: {items}")
    print(f"Конфиг: {config}")

process_data("Товар", 5, 99.99, True, [1, 2, 3], {"key": "value"})

3. Специфицирование типов контейнеров (typing.List, Dict, Tuple)

Для более точной типизации коллекций используй модуль typing:

from typing import List, Dict, Tuple, Set, Optional

def get_user_ids(users: List[Dict[str, str]]) -> List[int]:
    """Функция возвращает список ID пользователей."""
    return [int(user["id"]) for user in users]

users = [
    {"id": "1", "name": "Алиса"},
    {"id": "2", "name": "Боб"}
]

ids = get_user_ids(users)
print(ids)  # [1, 2]

def create_mapping(keys: List[str], values: List[int]) -> Dict[str, int]:
    """Создаёт словарь из списков ключей и значений."""
    return dict(zip(keys, values))

mapping = create_mapping(["a", "b", "c"], [1, 2, 3])
print(mapping)  # {"a": 1, "b": 2, "c": 3}

4. Union и Optional типы

from typing import Union, Optional

def parse_value(value: Union[str, int]) -> int:
    """Функция принимает строку или число и возвращает число."""
    if isinstance(value, str):
        return int(value)
    return value

print(parse_value("42"))  # 42
print(parse_value(42))     # 42

def get_user_email(user_id: int) -> Optional[str]:
    """Может вернуть None, если пользователь не найден."""
    users = {1: "alice@example.com", 2: "bob@example.com"}
    return users.get(user_id)  # Вернёт None, если нет

email = get_user_email(3)
print(email)  # None

5. Пользовательские типы (классы)

class User:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

class Database:
    def save_user(self, user: User) -> bool:
        """Сохраняет пользователя в БД."""
        print(f"Сохранён: {user.name}")
        return True

db = Database()
user = User("Иван", 30)
db.save_user(user)

6. Generics (параметризованные типы)

from typing import TypeVar, Generic, List

T = TypeVar("T")  # Определяем универсальный тип

class Stack(Generic[T]):
    """Стек с поддержкой любого типа элементов."""
    
    def __init__(self):
        self.items: List[T] = []
    
    def push(self, item: T) -> None:
        self.items.append(item)
    
    def pop(self) -> T:
        return self.items.pop()

# Стек для строк
string_stack: Stack[str] = Stack()
string_stack.push("Hello")
string_stack.push("World")
print(string_stack.pop())  # World

# Стек для чисел
int_stack: Stack[int] = Stack()
int_stack.push(1)
int_stack.push(2)
print(int_stack.pop())  # 2

7. Callable (функции как параметры)

from typing import Callable

def apply_operation(
    a: int,
    b: int,
    operation: Callable[[int, int], int]
) -> int:
    """Функция принимает другую функцию в качестве аргумента."""
    return operation(a, b)

def add(x: int, y: int) -> int:
    return x + y

def multiply(x: int, y: int) -> int:
    return x * y

print(apply_operation(5, 3, add))       # 8
print(apply_operation(5, 3, multiply))  # 15

8. Проверка типов с mypy

# Установка mypy
pip install mypy

# Проверка файла
mypy your_script.py

# Проверка всего проекта
mypy .

Пример ошибки, которую mypy обнаружит:

# script.py
def greet(name: str) -> str:
    return f"Hello, {name}!"

result = greet(123)  # Ошибка! Передаём int вместо str
$ mypy script.py
script.py:4: error: Argument 1 to "greet" has incompatible type "int"; expected "str"

9. Практический пример: валидация данных

from typing import List, Dict, Optional
from dataclasses import dataclass

@dataclass
class Product:
    name: str
    price: float
    quantity: int

def calculate_total(products: List[Product]) -> float:
    """Рассчитывает общую стоимость товаров."""
    return sum(p.price * p.quantity for p in products)

def get_product_by_name(
    products: List[Product],
    name: str
) -> Optional[Product]:
    """Ищет товар по названию."""
    for product in products:
        if product.name == name:
            return product
    return None

# Использование
products: List[Product] = [
    Product("Яблоко", 50.0, 10),
    Product("Груша", 70.0, 5),
    Product("Апельсин", 60.0, 8)
]

total = calculate_total(products)
print(f"Итого: {total} руб.")  # Итого: 1360.0 руб.

apple = get_product_by_name(products, "Яблоко")
if apple:
    print(f"Найден: {apple.name} по {apple.price} руб.")

10. Python 3.10+: match-case с типизацией

from typing import Union

def describe_value(value: Union[int, str, list]) -> str:
    match value:
        case int():
            return f"Число: {value}"
        case str():
            return f"Строка: {value}"
        case list():
            return f"Список из {len(value)} элементов"
        case _:
            return "Неизвестный тип"

print(describe_value(42))              # Число: 42
print(describe_value("Hello"))         # Строка: Hello
print(describe_value([1, 2, 3]))       # Список из 3 элементов

Лучшие практики

  1. Всегда типизируй функции — особенно публичные API
  2. Используй IDE — VSCode, PyCharm показывают подсказки типов
  3. Запускай mypy — добавь в CI/CD pipeline
  4. Будь конкретенList[str] лучше, чем list
  5. Используй Optional вместо None — яснее показывает намерение
  6. Не усложняй — типизация должна помогать, не мешать

Типизация в Python — это инвестиция в качество, читаемость и поддерживаемость кода!