I denne guide vil du forstå funktionaliteten og betydningen af if __name__ == ‘__main__’ i Python.
Har du nogensinde søgt gennem en Python-kodebase med forskellige moduler?
Hvis ja, ville du sandsynligvis være stødt på, om __name__ == ‘__main__’ er betinget i et eller flere moduler. I løbet af de næste par minutter vil vi afmystificere, hvad ovenstående betingede betyder, og se på et eksempel, hvor det kan være nyttigt.
Lad os begynde!
Indholdsfortegnelse
Hvad er betydningen af __navn__ i Python?
I Python er et modul en .py-fil, der indeholder funktionsdefinitioner, et sæt udtryk, der skal evalueres og mere. For eksempel, hvis vi har en fil ved navn hello_world.py, refererer vi til denne som hello_world.py-filen eller hello_world-modulet.
Når du kører et Python-modul, sætter Python-fortolkeren værdierne for nogle få specielle variabler forud for udførelse: __name__ er en af dem. Nøglen til at forstå betydningen __navn__ er at forstå, hvordan import fungerer i Python.
📁 Download koden til dette afsnit her.
Gå over til mappen eksempel-1. Vi har filen module1.py. Variablen __name__ er i navnerummet for det aktuelle modul.
Dette modul udskriver en linje efterfulgt af værdien af variablen __name__.
# example-1/module1.py print("This is module1.") print(f"The __name__ variable of module 1 is: {__name__}.")
Lad os nu køre modul1 fra kommandolinjen.
$ python module1.py
I outputtet ser vi, at variablen __name__ er sat til __main__.
This is module1. The __name__ variable of module 1 is: __main__.
Import af moduler i Python
Ud over at køre et Python-modul kan du nogle gange ønske at bruge funktionalitet fra et andet Python-modul inde i det aktuelle modul. Python letter dette gennem import.
Importer lader dig genbruge funktionaliteten af et andet modul – ved at importere det til det aktuelle moduls omfang – uden at skulle omskrive koden.
Modul2.py-filen indeholder følgende. Vi har importeret modul1 inde. modul 2.
# example-1/module2.py import module1 # module1 is imported print(f"This is module2") print(f"The __name__ variable of module2 is: {__name__}.")
Vi kører module2.py og observerer outputtet.
$ python module2.py
I outputtet nedenfor:
- Vi ser, at modul1 køres under emhætten, når vi importerer det inde i modul2, og det tilsvarende output printes ud.
- Men denne gang er variablen __name__ ikke __main__ men modul1.
- Fordi vi kørte modul2 direkte, er __name__-variablen, der svarer til modulet, nu __main__.
Output This is module1. The __name__ variable of module 1 is: module1. This is module2 The __name__ variable of module2 is: __main__.
💡 Nøgleidé:
– Hvis et modul køres direkte, er dets __name__ variabel sat til er lig med __main__.
– Hvis et modul importeres i et andet modul, er dets __navn__ sat til navnet på modulet.
Eksempel på if __name__==’__main__’ i Python
I afsnittet vil vi se en praktisk anvendelse af betingelsen if __name__ == ‘__main__’. Vi definerer en simpel funktion og skriver derefter enhedstests for at kontrollere, om funktionen fungerer som forventet.
📁 Download koden og følg med.
Koden til dette afsnit kan findes i mappen eksempel-2.
Her er add.py en Python-fil, der indeholder definitionen af funktionen add_ab(). Funktionen add_ab() indtager to vilkårlige tal og returnerer deres sum.
# example-2/add.py def add_ab(a,b): return a + b
Vi bruger Pythons unittest-modul til at teste funktionen add_ab().
Skrivning af testcases til en Python-funktion
Se på kodestykket nedenfor, der indeholder indholdet af test_add-modulet.
# 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)
Ovenstående kode gør følgende:
- Importerer Pythons indbyggede unittest-modul
- Importerer funktionen add_ab() fra add-modulet
- Definerer testklassen TestAdd og et sæt testcases som metoder inden for testklassen
For at opsætte enhedstests for din kode, skal du først definere en testklasse, der arver fra unittest.TestCase. Alle testcases skal angives som metoder inde i klassen og bør starte med test_.
Bemærk: Hvis du ikke navngiver metoderne som test_
Lad os nu prøve at køre test_add-modulet fra terminalen.
$ python test_add.py
Du vil se, at der ikke er noget output, og ingen af testene er kørt.
Hvorfor er dette tilfældet?🤔
Dette skyldes, at du for at køre enhedstestene skal køre unittest som hovedmodulet, mens du kører test_add.py ved at bruge kommandoen nedenfor.
$ python -m unittest test_add.py
Når vi kører ovenstående verbose kommando, ser vi, at alle tre tests har kørt med succes.
Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Det vil dog være praktisk at køre testene, når dette modul test_add køres, ja? Lad os lære, hvordan man gør det i næste afsnit.
Brug af if __name__ == ‘__main__’ til at køre unittest som hovedmodul
Hvis du gerne vil køre alle enhedstestene, når modulet kører direkte, kan du tilføje den betingede.
# 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()
Betingelsen i ovenstående kodestykke fortæller Python-fortolkeren: Hvis dette modul køres direkte, så kør koden inde. unittest.main().
Du kan køre test_add-modulet efter at have tilføjet ovenstående to linjer kode.
$ python test_add.py
▶️ Hvis du kører test-tilføj-modulet direkte nu, kører alle de tre test, vi har defineret.
Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Ovenstående output OK indikerer, at alle testene blev kørt med succes. De tre prikker … indikerer, at tre tests blev kørt, og alle bestod.
Lad os nu ændre den forventede returværdi test_add_1_minus7 til 8. Fordi funktionen returnerer – 6 i dette tilfælde, skulle der være en fejlende test.
def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), 8)
Som det ses i outputtet nedenfor, får vi .F., af de tre tests, mønster en af dem mislykkedes (den anden test), og i tracebacken får vi en AssertionError, der siger – 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)
En vigtig ting at bemærke er, at testene ikke nødvendigvis kører i samme rækkefølge, som de er angivet i testklassen. I ovenstående eksempel er test_add_1_minus7 defineret som den tredje metode i testklassen, men den tilsvarende test blev kørt som anden.
Opsummering
Jeg håber, at denne vejledning hjalp dig med at forstå, hvordan if __name__ == ‘__main__’ betinget virker i Python.
Her er en hurtig opsummering af de vigtigste takeaways:
- Python-fortolkeren indstiller variablen __name__, før Python-scriptet udføres.
- Når du kører et modul direkte, er værdien af __navn__ __main__.
- Når du importerer et modul i et andet Python-script, er værdien af __name__ modulnavnet.
- Du kan bruge if __name__ == ‘__main__’ til at styre udførelse og hvilke dele af modulet, der kører under henholdsvis direkte og importerede kørsler.
Tjek derefter denne dybdegående vejledning om Python-sæt. God læring!🎉