Pochopení if __name__ == ‚__main__‘ v Pythonu

V této příručce pochopíte funkčnost a význam if __name__ == ‚__main__‘ v Pythonu.

Prošli jste někdy kódovou základnu Pythonu s různými moduly?

Pokud ano, pravděpodobně byste se setkali s podmínkou, že __name__ == ‚__main__‘ je v jednom nebo více modulech podmíněno. Během několika příštích minut demystifikujeme, co výše uvedená podmínka znamená, a podíváme se na příklad, kde může být užitečná.

Pojďme začít!

Jaký je význam __name__ v Pythonu?

V Pythonu je modul soubor .py, který obsahuje definice funkcí, sadu výrazů k vyhodnocení a další. Pokud máme například soubor s názvem hello_world.py, označujeme jej jako soubor hello_world.py nebo modul hello_world.

Když spustíte modul Pythonu, interpret Pythonu nastaví před spuštěním hodnoty pro několik speciálních proměnných: __name__ je jednou z nich. Klíčem k pochopení významu __name__ je pochopení toho, jak fungují importy v Pythonu.

📁 Stáhněte si kód pro tuto sekci zde.

Přejděte do složky příklad-1. Máme soubor module1.py. Proměnná __name__ je ve jmenném prostoru aktuálního modulu.

Tento modul vytiskne řádek následovaný hodnotou proměnné __name__.

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

Nyní spusťte module1 z příkazového řádku.

$ python module1.py

Ve výstupu vidíme, že proměnná __name__ je nastavena na __main__.

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

Import modulů v Pythonu

Kromě spuštění modulu Python můžete někdy chtít použít funkce z jiného modulu Pythonu uvnitř aktuálního modulu. Python to usnadňuje pomocí importů.

  Ukládejte, komentujte a sdílejte webové úryvky na Androidu pomocí Nimbus Clipper

Importy vám umožňují znovu použít funkce jiného modulu – jeho importem do rozsahu aktuálního modulu – bez nutnosti přepisování kódu.

Soubor module2.py obsahuje následující. Uvnitř jsme importovali modul1. modul2.

# example-1/module2.py

import module1 # module1 is imported

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

Spustíme module2.py a pozorujeme výstup.

$ python module2.py

Ve výstupu níže:

  • Vidíme, že modul1 je spuštěn pod kapotou, když jej importujeme do modulu2, a vytiskne se odpovídající výstup.
  • Ale tentokrát proměnná __name__ není __main__, ale module1.
  • Protože jsme spustili modul module2 přímo, proměnná __name__ odpovídající modulu je nyní __main__.
Output

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

💡 Klíčová myšlenka:

– Pokud je modul spuštěn přímo, jeho proměnná __name__ je nastavena na hodnotu __main__.

– Pokud je modul importován do jiného modulu, jeho __name__ je nastaveno na název modulu.

Příklad if __name__==’__main__‘ v Pythonu

V této části uvidíme praktický případ použití podmínky if __name__ == ‚__main__‘. Definujeme jednoduchou funkci a poté napíšeme testy jednotek, abychom zkontrolovali, zda funkce funguje podle očekávání.

📁 Stáhněte si kód a postupujte podle něj.

Kód pro tuto sekci lze nalézt ve složce example-2.

Add.py je zde pythonovský soubor, který obsahuje definici funkce add_ab(). Funkce add_ab() přijímá libovolná dvě čísla a vrací jejich součet.

# example-2/add.py

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

K testování funkce add_ab() použijeme modul unittest Pythonu.

Psaní testovacích případů pro funkci Pythonu

Podívejte se na fragment kódu níže, který obsahuje obsah modulu 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)
    

Výše uvedený kód dělá následující:

  • Importuje vestavěný modul unittest Pythonu
  • Importuje funkci add_ab() z modulu add
  • Definuje třídu testu TestAdd a sadu testovacích případů jako metody v rámci třídy test
  Tento vyhledávač dokáže najít jakýkoli komiks Calvin & Hobbes na základě klíčového slova

Chcete-li pro svůj kód nastavit testy jednotek, měli byste nejprve definovat testovací třídu, která dědí z unittest.TestCase. Všechny testovací případy by měly být specifikovány jako metody uvnitř třídy a měly by začínat test_.

Poznámka: Pokud nepojmenujete metody jako test_, uvidíte, že odpovídající testy nebudou detekovány, a proto se nespustí.

Nyní zkusme spustit modul test_add z terminálu.

$ python test_add.py

Uvidíte, že neexistuje žádný výstup a neproběhl žádný z testů.

Proč tomu tak je?🤔

Je to proto, že ke spuštění testů jednotek byste měli spustit unittest jako hlavní modul při spuštění test_add.py pomocí příkazu níže.

$ python -m unittest test_add.py

Po spuštění výše uvedeného podrobného příkazu vidíme, že všechny tři testy proběhly úspěšně.

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

OK

Bude však vhodné spustit testy, když je spuštěn tento modul test_add, ano? V další části se naučíme, jak na to.

Použití if __name__ == ‚__main__‘ ke spuštění unittestu jako hlavního modulu

Pokud byste chtěli spustit všechny testy jednotek, když modul běží přímo, můžete přidat podmíněné.

# 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()

Podmínka ve výše uvedeném fragmentu kódu říká interpretu Pythonu: Pokud je tento modul spuštěn přímo, spusťte kód uvnitř. unittest.main().

  Jak stáhnout Google Meet

Modul test_add můžete spustit po přidání výše uvedených dvou řádků kódu.

$ python test_add.py

▶️ Přímé spuštění modulu pro přidání testu nyní spustí všechny tři testy, které jsme definovali.

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

OK

Výše uvedený výstup OK znamená, že všechny testy proběhly úspěšně. Tři tečky… znamenají, že byly provedeny tři testy a všechny prošly.

Nyní změňme očekávanou návratovou hodnotu test_add_1_minus7 na 8. Protože funkce vrací v tomto případě – 6, měl by být jeden test neúspěšný.

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

Jak je vidět na výstupu níže, dostaneme .F., ze tří testů, vzor jeden z nich selhal (druhý test) a ve tracebacku dostaneme AssertionError s uvedením – 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)

Jedna důležitá věc, kterou je třeba poznamenat, je, že testy nemusí nutně běžet ve stejném pořadí, v jakém jsou specifikovány v testovací třídě. Ve výše uvedeném příkladu je test_add_1_minus7 definována jako třetí metoda v testovací třídě, ale odpovídající test byl spuštěn jako druhý.

Shrnutí

Doufám, že vám tento tutoriál pomohl pochopit, jak podmínka if __name__ == ‚__main__‘ funguje v Pythonu.

Zde je stručná rekapitulace klíčových informací:

  • Interpret Pythonu nastaví proměnnou __name__ před spuštěním skriptu Python.
  • Když spustíte modul přímo, hodnota __name__ je __main__.
  • Když importujete modul do jiného skriptu Pythonu, hodnota __name__ je název modulu.
  • Můžete použít if __name__ == ‚__main__‘ ke kontrole provádění a toho, které části modulu se spouštějí během přímých a importovaných běhů.

Dále se podívejte na tohoto podrobného průvodce sadami Pythonu. Příjemné učení! 🎉