Документация и docstrings
Документация — это описание кода, которое помогает разработчикам понимать, как работают функции и другие компоненты программы. В Python документация функции обычно записывается в виде docstring — строки в тройных кавычках, расположенной сразу после заголовка функции.
# docstring_demo.py
def greet(name: str) -> str:
"""Возвращает приветственное сообщение для пользователя.
:param name: Имя пользователя.
:return: Строка приветствия.
"""
return f"Hello, {name}!"
print(greet("Alice"))
print(help(greet))
В отличие от обычных комментариев #, docstrings сохраняются как атрибут __doc__ и доступны через help().
Функция help()
help(object) выводит документацию объекта: его docstring, параметры и другие сведения. Если вызвать help() без аргументов, откроется интерактивный справочный режим.
# help_demo.py
help(sum)
help(str)
help(greet)
Аннотации типов
Аннотации типов — это механизм, позволяющий указывать ожидаемые типы аргументов и возвращаемого значения функции, а также типы переменных.
# type_hints_demo.py
def add(a: int, b: int) -> int:
return a + b
num: int = 10
print(add(3, 5))
print(add("3", "5")) # не вызовет ошибку во время выполнения
mypy).
Аннотации для коллекций
В Python 3.9+ для списков, кортежей, множеств и словарей можно использовать встроенные типы с указанием содержимого:
# collection_type_hints.py
def process_numbers(numbers: list[int]) -> list[int]:
"""Возвращает список квадратов чисел."""
return [n ** 2 for n in numbers]
def unique_chars(text: str) -> set[str]:
"""Возвращает множество уникальных символов."""
return set(text)
def count_words(text: str) -> dict[str, int]:
"""Считает частоту каждого слова в строке."""
words = text.split()
return {word: words.count(word) for word in set(words)}
typing: List[int], Dict[str, int] и т.д. В современном коде рекомендуется встроенный синтаксис list[int].
Работа со словарями
Словари удобно преобразовывать: инвертировать ключи и значения, заменять значения по другому словарю, фильтровать пары.
# dict_transform.py
original_dict = {"a": 1, "b": 2, "c": 3}
inverted_dict = {value: key for key, value in original_dict.items()}
print(inverted_dict)
number_to_word = {1: "один", 2: "два", 3: "три"}
data = {"x": 1, "y": 2, "z": 3}
translated = {
key: number_to_word.get(value, value)
for key, value in data.items()
}
print(translated)
Рекурсия: базовый и рекурсивный случай
Рекурсия — это когда функция вызывает сама себя для решения уменьшенной версии задачи. Любая корректная рекурсия состоит из двух частей:
- Базовый случай — условие остановки.
- Рекурсивный случай — вызов себя с более простыми данными.
# factorial.py
def factorial(n: int) -> int:
"""Возвращает факториал неотрицательного целого числа."""
if n == 0 or n == 1: # базовый случай
return 1
return n * factorial(n - 1) # рекурсивный случай
print(factorial(5)) # 120
Хвостовая рекурсия
Хвостовая рекурсия — частный случай, при котором рекурсивный вызов является последней операцией функции. В некоторых языках такой вызов оптимизируется, но в Python это не работает.
# tail_recursion.py
def factorial_tail(n: int, accumulator: int = 1) -> int:
if n == 0 or n == 1:
return accumulator
return factorial_tail(n - 1, n * accumulator)
print(factorial_tail(5)) # 120
Для глубоких вычислений используйте итерацию:
# iterative_factorial.py
def factorial_iterative(n: int) -> int:
accumulator = 1
while n > 1:
accumulator *= n
n -= 1
return accumulator
print(factorial_iterative(5)) # 120
Рекурсия или итерация?
| Критерий | Рекурсия | Итерация |
|---|---|---|
| Читаемость | Высокая для деревьев, графов, вложенных структур | Выше для простых последовательностей |
| Память | Стек вызовов растёт с глубиной | Обычно меньше |
| Скорость | Медленнее из-за накладных расходов | Быстрее |
| Риск | RecursionError | Бесконечный цикл |
| Когда использовать | Деревья, графы, вложенные данные, разбор выражений | Простые переборы, большие глубины |
Глубокое копирование
Функция deepcopy() из модуля copy использует рекурсию, чтобы создать полностью независимую копию объекта. Обычный copy() копирует только верхний уровень.
# deepcopy_demo.py
from copy import deepcopy
original_list = [[1, 2], [3, 4]]
copy_lst = deepcopy(original_list)
copy_lst[0][0] = "X"
print("Оригинал:", original_list) # [[1, 2], [3, 4]]
print("Копия:", copy_lst) # [['X', 2], [3, 4]]
deepcopy() для циклических ссылок, пользовательских классов и слабых ссылок сверяйте с официальной документацией модуля copy.