📜 Как показано в исходном материале
Исходная лекция уже использует аннотации типов и читаемые имена. Пример функции с docstring:
# из исходника
def greet(name):
"""
Функция принимает имя и возвращает строку приветствия.
:param name: Имя пользователя.
:return: Приветственное сообщение.
"""
return f"Hello, {name}!"
Пример замены значений в словаре:
# из исходника
data = {"x": 1, "y": 2, "z": 3}
number_to_word = {1: "один", 2: "два", 3: "три"}
for key in data:
if data[key] in number_to_word:
data[key] = number_to_word[data[key]]
print(data)
Этот код корректен, но изменяет исходный словарь и не использует аннотации типов.
❌ Что можно улучшить
- Нет аннотаций типов в учебных примерах.
- Изменение исходного словаря вместо создания нового может привести к побочным эффектам.
- Проверка
data[key] in number_to_wordменее удобна, чемnumber_to_word.get(...). - Рекурсивные функции не всегда защищены от отрицательных аргументов.
✅ Рекомендуемый современный вариант
# modern_greet.py
def greet(name: str) -> str:
"""Возвращает приветственное сообщение для пользователя.
:param name: Имя пользователя.
:return: Строка приветствия.
"""
return f"Hello, {name}!"
Современная замена значений в словаре:
# modern_translate.py
def translate_values(
data: dict[str, int],
mapping: dict[int, str]
) -> dict[str, str]:
"""Заменяет числовые значения словаря на строки по mapping."""
return {
key: mapping.get(value, str(value))
for key, value in data.items()
}
number_to_word = {1: "один", 2: "два", 3: "три"}
data = {"x": 1, "y": 2, "z": 3}
print(translate_values(data, number_to_word))
Что улучшилось:
- Функция чистая — не изменяет исходный словарь.
- Аннотации типов делают контракт явным.
mapping.get(value, str(value))короче и безопаснее.
Современный факториал
# modern_factorial.py
def factorial(n: int) -> int:
"""Возвращает факториал неотрицательного целого числа n."""
if n < 0:
raise ValueError("n must be non-negative")
if n == 0 or n == 1:
return 1
return n * factorial(n - 1)
Замена хвостовой рекурсии на итерацию
# modern_iterative_factorial.py
def factorial_iterative(n: int) -> int:
"""Итеративный факториал без риска переполнения стека."""
if n < 0:
raise ValueError("n must be non-negative")
accumulator = 1
while n > 1:
accumulator *= n
n -= 1
return accumulator
🕰️ Когда старый подход ещё можно встретить
Учебные материалы и простые скрипты часто пишут без аннотаций и guard clauses. Это нормально для быстрых экспериментов, но в production-коде и домашних заданиях стоит добавлять проверки и документацию.