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!
Table of Contents
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ů.
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
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_
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().
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í! 🎉