if __name__ == '__main__' в Python: зачем нужен и как правильно использовать
Конструкция if __name__ == '__main__': — один из базовых кирпичиков Python. Она определяет «точку входа» скрипта, помогает избежать побочных эффектов при импорте и делает код переиспользуемым. В статье разберёмся, как это работает, когда и зачем применять, и покажем практические примеры.
Что такое __name__ и почему '__main__'
При запуске файла как скрипта интерпретатор устанавливает переменную __name__ в значение '__main__'. Если же файл импортируют как модуль, __name__ равно имени модуля (например, 'utils').
# foo.py
print(__name__)
# Запуск: python foo.py
# Вывод: __main__
# Импорт из интерактивной сессии:
# >>> import foo
# Вывод при импорте: foo
Отсюда и паттерн: оборачиваем «исполняемую» часть под проверку if __name__ == '__main__':, чтобы этот код выполнялся только при прямом запуске, а не при импорте.
Базовый шаблон с main()
Рекомендуется выносить логику запуска в функцию main() и возвращать код завершения. Так проще тестировать и переиспользовать модуль.
# app.py
import argparse
def main() -> int:
parser = argparse.ArgumentParser(description="Демо CLI")
parser.add_argument("name", help="Имя пользователя")
args = parser.parse_args()
print(f"Привет, {args.name}!")
return 0
if __name__ == "__main__":
raise SystemExit(main())
Такой подход хорош и для маленьких утилит, и для серьёзных приложений: импортируя app из других мест, вы не получите побочных эффектов.
Зачем это нужно на практике
- Избежать побочных эффектов при импорте: демонстрационный или запускной код не выполнится автоматически.
- Повторное использование: модуль можно безопасно импортировать из тестов или других модулей.
- Удобный CLI: отделяем парсинг аргументов и инициализацию от библиотечной логики.
- Чистая структура проекта: понятно, где точка входа и что именно запускается.
Модуль как пакет: запуск через python -m
Иногда удобнее запускать не файл, а модуль внутри пакета: python -m package.module. Для запуска всего пакета создайте __main__.py — это будет его точка входа.
# Структура
myapp/
├─ __init__.py
├─ __main__.py
└─ cli.py
# myapp/__main__.py
def main() -> int:
print("Запуск пакета myapp")
return 0
if __name__ == "__main__":
raise SystemExit(main())
# Запуск: python -m myapp
Преимущество python -m — корректная настройка путей импорта и удобный способ упаковки CLI-утилит внутри пакетов.
Практические мини-примеры
1) Библиотечные функции + демонстрация
# utils.py
def add(a: int, b: int) -> int:
return a + b
if __name__ == "__main__":
# Демонстрация работы: выполняется только при прямом запуске файла
print(add(2, 3)) # 5
Импортируя utils из других модулей, вы не получите нежелательный вывод в консоль.
2) Интеграция с doctest
# mathx.py
def square(x: int) -> int:
"""Квадрат числа.
>>> square(4)
16
"""
return x * x
if __name__ == "__main__":
import doctest
raise SystemExit(0 if doctest.testmod().failed == 0 else 1)
Теперь python mathx.py прогонит встроенные примеры как тесты, а импорт mathx не запустит тесты самопроизвольно.
3) Несколько CLI-точек в одном проекте
# tools/report.py
import sys
def main() -> int:
print("Генерация отчёта...")
return 0
if __name__ == "__main__":
sys.exit(main())
# Запуск: python -m tools.report
Типичные ошибки и как их избежать
- Исполняемый код вне гард-блока. Решение: всё, что не должно работать при импорте (парсинг аргументов, I/O, запуск демо), кладите под
if __name__ == '__main__':. - Отсутствует
main(). Лучше иметь одну точку запуска, возвращать код завершения и вызыватьSystemExit(main()). - Глобальные побочные эффекты. Сведите к минимуму глобальные операции (подключение БД, чтение файлов) вне функций.
- Смешение библиотечного кода и CLI. Выделяйте библиотечные функции отдельно, а обвязку — под гард-блок.
- print вместо логирования. Для реальных проектов используйте
logging— будет проще управлять уровнем выводов.
Частые вопросы (коротко)
- Можно ли иметь несколько точек входа? Да, в разных модулях/пакетах. Запускайте нужный через файл или
python -m. - Нужен ли гард для библиотек? Да, если есть демонстрация/ручной запуск/встроенные тесты — поместите их под гард.
- Чем
python -mлучше прямого запуска файла? Он корректно настраивает импорты внутри пакета и удобен для распространения CLI.
Итоги
if __name__ == '__main__': — простой, но критически важный приём: он задаёт точку входа, устраняет побочные эффекты при импорте и помогает строить понятную архитектуру модулей и пакетов. Освоив этот шаблон вместе с main() и python -m, вы сделаете свой код надёжнее и удобнее для тестирования и повторного использования.
Хотите системно прокачать основы и быстро перейти к практике? Рекомендую пошаговый курс «Python с нуля до Гуру» — начать обучение и получить готовые мини‑проекты.
-
Создано 10.06.2026 17:02:24
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.