Проверка __name__
В прошлом уроке мы увидели, что import выполняет файл модуля целиком. Вернёмся в мастерскую. Свой ящик с инструментами вы открываете на своём верстаке и сразу пробуете: включаете дрель, проверяете пилу. Но ящик можно одолжить соседу, и тогда пробный запуск ему не нужен — сосед возьмёт только инструменты.
С файлом .py происходит то же самое. Допустим, в конце greet.py стоит проверочный вызов print(hello("Ann")). Он сработает не только при запуске greet.py, но и у каждой программы, которая подключит greet. Файлу нужен способ узнать, запустили его напрямую или подключили.
Для этого интерпретатор задаёт в каждом модуле переменную __name__. Это как наклейка на ящике: по ней видно, открыли ящик дома или одолжили:
def hello(name):
return f"Hello, {name}"
print(__name__) # __main__
if __name__ == "__main__":
print(hello("Ann")) # Hello, AnnДавайте разберём, что происходит при запуске этого файла:
def helloсоздаёт функцию, но пока её не вызывает.print(__name__)печатает__main__: файл запустили напрямую.- Условие
__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 и вызывают её под проверкой:
def main():
print("report ready")
if __name__ == "__main__":
main() # report readyПеременные внутри main локальные, поэтому они не попадают в модуль и не мешают тем, кто его подключает. Так файл служит двум целям:
- запущенный напрямую, он работает как программа и вызывает
main; - подключённый, он отдаёт свои функции и ничего не печатает.
Если файл называется report.py, подключивший его код может вызвать и report.main() сам.
Проверки в задачах курса тоже подключают ваш файл через import, поэтому вызовы для пробы держите под этим условием. На собеседовании часто спрашивают, зачем нужна строка if __name__ == "__main__":. Ответ: чтобы код под ней выполнялся при прямом запуске файла и не выполнялся при импорте.
Частая ошибка
В условии забыли кавычки:
if __name__ == __main__: # ✗
print("start")NameError: name '__main__' is not defined. Did you mean: '__name__'?__name__ — переменная, а "__main__" — строка, с которой её сравнивают. Без кавычек интерпретатор ищет переменную с именем __main__ и не находит её. В строке нужны те же два подчёркивания с каждой стороны, иначе условие никогда не станет истинным.
Главное
- Интерпретатор задаёт
__name__в каждом модуле сам. - При прямом запуске файла
__name__равен"__main__", при импорте — имени модуля. - Код под
if __name__ == "__main__":выполняется только при прямом запуске. "__main__"в условии — строка, поэтому её пишут в кавычках.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.