Оригінальна публікація: Python if __name__ == __main__ Explained with Code Examples

Коли інтерпретатор Python читає файл Python, спочатку він налаштовує декілька спеціальних змінних. Потім він виконує код з файлу.

Однією з цих змінних є __name__.

Якщо дотримуватись цієї публікації та прочитати сніпети, то можна зрозуміти, як використовувати if __name__ == "__main__" та чому це важливо.

Модулі у Python

Модулями називаються файли у Python з розширенням .py. Модуль може визначати функції, класи та змінні.

Тому коли інтерпретатор запускає модуль, змінна __name__ буде налаштована як __main__, якщо модуль запущено у головній програмі.

Якщо код імпортує модуль з іншого модуля, тоді змінна __name__  буде налаштована як назва того модуля.

Розглянемо приклад. Створіть модуль Python під назвою file_one.py та вставте в нього цей код верхнього рівня:

# Python file one module

print("File one __name__ is set to: {}" .format(__name__))
file_one.py

Запустивши цей файл ви зрозумієте, про що ми говорили. Змінна __name__ для цього модуля налаштована як __main__:

File one __name__ is set to: __main__

Тепер додайте ще один файл під назвою file_two.py та вставте цей код всередину:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))
file_two.py

Крім того, змініть код у file_one.py, щоб імпортувати модуль file_two:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))
file_one.py

Якщо запустити код file_one ще раз, то побачимо, що змінна __name__ у файлі file_one не змінилась та досі налаштована як __main__. Але тепер змінна __name__ у file_two налаштована як назва модуля, тобто file_two.

Результат буде приблизно таким:

File two __name__ is set to: file_two
File one __name__ is set to: __main__

Однак під час прямого запуску file_two ми побачимо, що назва налаштована як __main__:

File two __name__ is set to: __main__

Змінна __name__ для файлу/модуля, який виконується, завжди буде __main__. Але змінна __name__ для всіх інших імпортованих модулів буде налаштована як назва модуля.

Конвенції іменування файлів Python

Зазвичай __name__ та __main__ використовують так:

if __name__ == "__main__":
   Do something here

Розглянемо, як це працює у реальному житті та як використовувати ці змінні.

Змініть file_one та file_two таким чином, щоб вони виглядали ось так:

file_one:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
file_one.py

file_two:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
file_two.py

Знову ж таки, під час запуску file_one ви побачите, що програма розпізнала, який з двох модулів __main__ та виконала код відповідно до наших перших інструкцій if else.

Результат виглядатиме так:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly

Тепер запустіть file_two та ви побачите, що змінна __name__ налаштована як __main__:

File two __name__ is set to: __main__
File two executed when ran directly

Коли подібні модулі імпортуються та запускаються, будуть імпортовані їхні функції та виконуватиметься код верхнього рівня.

Щоб побачити цей процес у дії, змініть свої файли таким чином:

file_one:

# Python module to execute
import file_two

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
else:
   print("File one executed when imported")
file_one.py

file_two:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")

Тепер функції завантажуються, але не запускаються.

Щоб запустити одну з цих функцій, змініть частину if __name__ == "__main__" у file_one таким чином:

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
else:
   print("File one executed when imported")

При запуску file_one ви повинні побачити наступне:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed

Ви також можете запустити функції з імпортованих файлів. Для цього змініть частину if __name__ == “__main__” у file_one наступним чином:

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   file_two.function_three()
else:
   print("File one executed when imported")

І ви можете очікувати такий результат:

File two __name__ is set to: file_two
File two executed when imported
File one __name__ is set to: __main__
File one executed when ran directly
Function two is executed
Function three is executed

Тепер припустимо, що модуль file_two містить безліч функцій (у нашому випадку дві), та ви не хочете імпортувати всі. Змініть file_two наступним чином:

# Python module to import

print("File two __name__ is set to: {}" .format(__name__))

def function_three():
   print("Function three is executed")

def function_four():
   print("Function four is executed")

if __name__ == "__main__":
   print("File two executed when ran directly")
else:
   print("File two executed when imported")
file_two.py

А щоб імпортувати певні функції з модуля, використайте блок імпорту from у файлі file_one:

# Python module to execute
from file_two import function_three

print("File one __name__ is set to: {}" .format(__name__))

def function_one():
   print("Function one is executed")

def function_two():
   print("Function two is executed")

if __name__ == "__main__":
   print("File one executed when ran directly")
   function_two()
   function_three()
else:
   print("File one executed when imported")
file_one.py

Висновок

Існує хороший приклад використання змінної __name__, незалежно від того, чи потрібен вам файл, який можна запускати як основну програму чи імпортувати іншими модулями. Можна використати блок if __name__ == "__main__", щоб дозволити або заборонити виконання певних частин коду під час імпорту модулів.

Коли інтерпретатор Python читає файл, змінна __name__ налаштована як __main__ (якщо виконується модуль) або як назва модуля (якщо імпортується). Читання файлу виконує весь код верхнього рівня, але не функції та класи (оскільки вони будуть лише імпортовані).

Bra gjort! (шведською це означає «Хороша робота!»)