Перейти к содержимому
Теория · Модули, файлы и генераторы · урок 2 из 12

Проверка __name__

В прошлом уроке мы увидели, что import выполняет файл модуля целиком. Вернёмся в мастерскую. Свой ящик с инструментами вы открываете на своём верстаке и сразу пробуете: включаете дрель, проверяете пилу. Но ящик можно одолжить соседу, и тогда пробный запуск ему не нужен — сосед возьмёт только инструменты.

С файлом .py происходит то же самое. Допустим, в конце greet.py стоит проверочный вызов print(hello("Ann")). Он сработает не только при запуске greet.py, но и у каждой программы, которая подключит greet. Файлу нужен способ узнать, запустили его напрямую или подключили.

Для этого интерпретатор задаёт в каждом модуле переменную __name__. Это как наклейка на ящике: по ней видно, открыли ящик дома или одолжили:

Python
def hello(name):
    return f"Hello, {name}"


print(__name__)  # __main__
if __name__ == "__main__":
    print(hello("Ann"))  # Hello, Ann

Давайте разберём, что происходит при запуске этого файла:

  1. def hello создаёт функцию, но пока её не вызывает.
  2. print(__name__) печатает __main__: файл запустили напрямую.
  3. Условие __name__ == "__main__" истинно, и проверочный вызов печатает Hello, Ann.

Откуда берётся значение

Значение __name__ зависит только от способа запуска. Вариантов два.

Файл запустили напрямую

Файл, который запустили командой python greet.py, получает в __name__ строку "__main__". Это главный файл программы — тот, с которого всё началось.

Файл подключили через import

Модуль, подключённый через import, получает своё имя — имя файла без .py. Если тот же greet.py подключить из другой программы, в нём __name__ равен "greet". Условие ложно, и проверочный вызов не выполнится.

Пусть в greet.py есть строка print(__name__), а в app.py — строка import greet. Команда python greet.py напечатает __main__, а команда python app.py напечатает greet. Имя есть и у модулей стандартной библиотеки: после import json вызов print(json.__name__) печатает json. У модуля внутри пакета имя полное, через точку: shop.cart.

Два подчёркивания с каждой стороны отмечают служебные имена, с которыми работает сам интерпретатор: __name__ он задаёт, а __init__ вызывает. Здесь аналогия с наклейкой заканчивается: наклейку на ящик клеите вы, а __name__ всегда задаёт интерпретатор.

Функция main

Код, который должен работать только при прямом запуске, обычно собирают в функцию main и вызывают её под проверкой:

Python
def main():
    print("report ready")


if __name__ == "__main__":
    main()  # report ready

Переменные внутри main локальные, поэтому они не попадают в модуль и не мешают тем, кто его подключает. Так файл служит двум целям:

  • запущенный напрямую, он работает как программа и вызывает main;
  • подключённый, он отдаёт свои функции и ничего не печатает.

Если файл называется report.py, подключивший его код может вызвать и report.main() сам.

Проверки в задачах курса тоже подключают ваш файл через import, поэтому вызовы для пробы держите под этим условием. На собеседовании часто спрашивают, зачем нужна строка if __name__ == "__main__":. Ответ: чтобы код под ней выполнялся при прямом запуске файла и не выполнялся при импорте.

Частая ошибка

В условии забыли кавычки:

Python
if __name__ == __main__:  # ✗
    print("start")
TEXT
NameError: name '__main__' is not defined. Did you mean: '__name__'?

__name__ — переменная, а "__main__" — строка, с которой её сравнивают. Без кавычек интерпретатор ищет переменную с именем __main__ и не находит её. В строке нужны те же два подчёркивания с каждой стороны, иначе условие никогда не станет истинным.

Главное

  • Интерпретатор задаёт __name__ в каждом модуле сам.
  • При прямом запуске файла __name__ равен "__main__", при импорте — имени модуля.
  • Код под if __name__ == "__main__": выполняется только при прямом запуске.
  • "__main__" в условии — строка, поэтому её пишут в кавычках.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом