Розуміння того, якщо __name__ == ‘__main__’ у Python

У цьому посібнику ви зрозумієте функціональність і значення if __name__ == ‘__main__’ у Python.

Ви коли-небудь переглядали кодову базу Python із різними модулями?

Якщо так, ви, ймовірно, зустріли умовний оператор if __name__ == ‘__main__’ в одному або кількох модулях. Протягом наступних кількох хвилин ми демістифікуємо значення наведеного вище умови та розглянемо приклад, де це може бути корисним.

Давайте почнемо!

Яке значення __name__ у Python?

У Python модуль — це файл .py, який містить визначення функцій, набір виразів для оцінки тощо. Наприклад, якщо у нас є файл з назвою hello_world.py, ми називаємо його файлом hello_world.py або модулем hello_world.

Коли ви запускаєте модуль Python, інтерпретатор Python встановлює значення для кількох спеціальних змінних перед виконанням: __name__ — одна з них. Ключем до розуміння значення __name__ є розуміння того, як імпорт працює в Python.

📁 Завантажте код для цього розділу тут.

Перейдіть до папки example-1. У нас є файл module1.py. Змінна __name__ знаходиться в просторі імен поточного модуля.

Цей модуль друкує рядок, за яким слідує значення змінної __name__.

# example-1/module1.py
print("This is module1.")
print(f"The __name__ variable of module 1 is: {__name__}.")

Тепер давайте запустимо module1 з командного рядка.

$ python module1.py

У вихідних даних ми бачимо, що змінна __name__ має значення __main__.

This is module1.
The __name__ variable of module 1 is: __main__.

Імпорт модулів у Python

На додаток до запуску модуля Python, іноді ви можете використовувати функціональні можливості іншого модуля Python всередині поточного модуля. Python полегшує це через імпорт.

Імпорт дозволяє повторно використовувати функціональність іншого модуля, імпортувавши його в область поточного модуля, без необхідності переписувати код.

  Як поділитися своїми Apple Maps Live ETA на iPhone

Файл module2.py містить наступне. Ми імпортували module1 всередині. модуль2.

# example-1/module2.py

import module1 # module1 is imported

print(f"This is module2")
print(f"The __name__ variable of module2 is: {__name__}.")

Ми запускаємо module2.py і спостерігаємо за результатом.

$ python module2.py

У вихідних даних нижче:

  • Ми бачимо, що modul1 виконується під капотом, коли ми імпортуємо його в module2, і відповідний вихід роздруковується.
  • Але цього разу змінна __name__ не є __main__, а module1.
  • Оскільки ми запускали module2 безпосередньо, змінна __name__, що відповідає модулю, тепер __main__.
Output

This is module1.
The __name__ variable of module 1 is: module1.
This is module2
The __name__ variable of module2 is: __main__.

💡 Ключова ідея:

– Якщо модуль запускається безпосередньо, його змінна __name__ має значення __main__.

– Якщо модуль імпортується в інший модуль, його __name__ встановлюється на ім’я модуля.

Приклад if __name__==’__main__’ у Python

У цьому розділі ми побачимо приклад практичного використання умовного оператора if __name__ == ‘__main__’. Ми визначимо просту функцію, а потім напишемо модульні тести, щоб перевірити, чи функція працює належним чином.

📁 Завантажте код і дотримуйтесь.

Код цього розділу можна знайти в папці example-2.

Тут add.py — це файл Python, який містить визначення функції add_ab(). Функція add_ab() приймає будь-які два числа та повертає їх суму.

# example-2/add.py

def add_ab(a,b):
    return a + b

Ми використаємо модуль unittest Python, щоб перевірити функцію add_ab().

Написання тестових випадків для функції Python

Перегляньте наведений нижче фрагмент коду, який містить вміст модуля test_add.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)
    

Наведений вище код робить наступне:

  • Імпортує вбудований модуль unittest Python
  • Імпортує функцію add_ab() із модуля add
  • Визначає тестовий клас TestAdd і набір тестових випадків як методи в межах тестового класу
  Як купити віртуальну землю в Метавсесвіті?

Щоб налаштувати модульні тести для свого коду, вам слід спочатку визначити тестовий клас, який успадковує unittest.TestCase. Усі тестові випадки мають бути визначені як методи всередині класу та мають починатися з test_.

Примітка. Якщо ви не назвете методи як test_, ви побачите, що відповідні тести не будуть виявлені, а отже, не виконуватимуться.

Тепер давайте спробуємо запустити модуль test_add з терміналу.

$ python test_add.py

Ви побачите, що вихідних даних немає, і жоден із тестів не виконано.

Чому це так?🤔

Це пояснюється тим, що для запуску модульних тестів вам слід запустити unittest як основний модуль під час запуску test_add.py, використовуючи наведену нижче команду.

$ python -m unittest test_add.py

Після виконання наведеної вище команди ми бачимо, що всі три тести виконано успішно.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Однак буде зручно запускати тести, коли запущено цей модуль test_add, так? Давайте дізнаємося, як це зробити, у наступному розділі.

Використання if __name__ == ‘__main__’ для запуску unittest як основного модуля

Якщо ви хочете запустити всі модульні тести, коли модуль запускається безпосередньо, ви можете додати умовний оператор.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)

# Run unittest as the main module
if __name__ == '__main__':
        unittest.main()

Умовний оператор у наведеному вище фрагменті коду повідомляє інтерпретатору Python: якщо цей модуль запускається безпосередньо, запустіть код усередині. unittest.main().

Ви можете запустити модуль test_add після додавання двох вищезазначених рядків коду.

$ python test_add.py

▶️ Безпосередній запуск модуля додавання тесту запускає всі три тести, які ми визначили.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

Наведений вище результат OK означає, що всі тести виконано успішно. Три крапки … означають, що було проведено три тести, і всі вони пройшли.

  Як створити висячий відступ у Word і Google Docs

Тепер давайте змінимо очікуване повернуте значення test_add_1_minus7 на 8. Оскільки в цьому випадку функція повертає – 6, має бути один невдалий тест.

def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), 8)

Як видно з вихідних даних нижче, ми отримуємо .F., з трьох тестів, шаблон одного з них невдалий (другий тест), а в трасуванні ми отримуємо AssertionError із зазначенням – 6 != 8.

Output
.F.
======================================================================
FAIL: test_add_1_minus7 (__main__.TestAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_add.py", line 12, in test_add_1_minus7
    self.assertEqual(add_ab(1,-7), 8)
AssertionError: -6 != 8

----------------------------------------------------------------------
Ran 3 tests in 0.021s

FAILED (failures=1)

Важливо зауважити, що тести не обов’язково виконуються в тому порядку, в якому вони вказані в тестовому класі. У наведеному вище прикладі test_add_1_minus7 визначено як третій метод у тестовому класі, але відповідний тест було запущено другим.

Підводячи підсумки

Сподіваюся, цей посібник допоміг вам зрозуміти, як умовний оператор if __name__ == ‘__main__’ працює в Python.

Ось короткий підсумок основних висновків:

  • Інтерпретатор Python встановлює змінну __name__ перед виконанням сценарію Python.
  • Коли ви запускаєте модуль безпосередньо, значення __name__ дорівнює __main__.
  • Коли ви імпортуєте модуль в інший сценарій Python, значення __name__ є назвою модуля.
  • Ви можете використовувати if __name__ == ‘__main__’, щоб керувати виконанням і тим, які частини модуля запускаються під час прямого та імпортованого запуску відповідно.

Далі перегляньте цей докладний посібник про набори Python. Гарного навчання!🎉