Înțelegerea dacă __name__ == ‘__main__’ în Python

În acest ghid, veți înțelege funcționalitatea și semnificația if __name__ == ‘__main__’ în Python.

Ați parcurs vreodată o bază de cod Python cu module diferite?

Dacă da, probabil că ați fi întâlnit dacă __name__ == „__main__” condiționat într-unul sau mai multe module. În următoarele câteva minute, vom demistifica ce înseamnă condiționalul de mai sus și vom analiza un exemplu în care poate fi util.

Sa incepem!

Care este semnificația __name__ în Python?

În Python, un modul este un fișier .py care conține definiții de funcții, un set de expresii care trebuie evaluate și multe altele. De exemplu, dacă avem un fișier numit hello_world.py, ne referim la acesta ca fișier hello_world.py sau modulul hello_world.

Când rulați un modul Python, interpretul Python setează valorile pentru câteva variabile speciale înainte de execuție: __name__ este una dintre ele. Cheia pentru înțelegerea semnificației __name__ este înțelegerea modului în care funcționează importurile în Python.

📁 Descarcă aici codul pentru această secțiune.

Mergeți la folderul exemplu-1. Avem fișierul module1.py. Variabila __name__ se află în spațiul de nume al modulului curent.

Acest modul tipărește o linie urmată de valoarea variabilei __name__.

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

Acum, să rulăm module1 din linia de comandă.

$ python module1.py

În rezultat, vedem că variabila __name__ este setată la __main__.

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

Importul modulelor în Python

Pe lângă rularea unui modul Python, s-ar putea să doriți uneori să utilizați funcționalitatea unui alt modul Python în interiorul modulului curent. Python facilitează acest lucru prin importuri.

  Ce este și rolul său în securitatea în cloud?

Importurile vă permit să reutilizați funcționalitatea altui modul, importându-l în domeniul de aplicare al modulului curent, fără a fi nevoie să rescrieți codul.

Fișierul module2.py conține următoarele. Am importat module1 în interior. modulul 2.

# example-1/module2.py

import module1 # module1 is imported

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

Rulăm module2.py și observăm rezultatul.

$ python module2.py

În rezultatul de mai jos:

  • Vedem că module1 este rulat sub capotă atunci când îl importăm în interiorul module2, iar rezultatul corespunzător este tipărit.
  • Dar de data aceasta, variabila __name__ nu este __main__ ci module1.
  • Deoarece am rulat module2 direct, variabila __name__ corespunzătoare modulului este acum __main__.
Output

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

💡 Idee cheie:

– Dacă un modul este rulat direct, variabila sa __name__ este setată la este egală cu __main__.

– Dacă un modul este importat în interiorul altui modul, __name__ este setat la numele modulului.

Exemplu de if __name__==’__main__’ în Python

În secțiune, vom vedea un caz practic de utilizare a condiționalului if __name__ == ‘__main__’. Vom defini o funcție simplă și apoi vom scrie teste unitare pentru a verifica dacă funcția funcționează conform așteptărilor.

📁 Descărcați codul și urmăriți.

Codul pentru această secțiune poate fi găsit în folderul exemplu-2.

Aici, add.py este un fișier Python care conține definiția funcției add_ab(). Funcția add_ab() preia orice două numere și returnează suma acestora.

# example-2/add.py

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

Vom folosi modulul unittest al lui Python pentru a testa funcția add_ab().

Scrierea cazurilor de testare pentru o funcție Python

Priviți fragmentul de cod de mai jos, care conține conținutul modulului 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)
    

Codul de mai sus face următoarele:

  • Importă modulul unittest încorporat din Python
  • Importă funcția add_ab() din modulul add
  • Definește clasa de test TestAdd și un set de cazuri de testare ca metode în cadrul clasei de test
  11 cel mai bun software de management de produs pentru aplicații moderne

Pentru a configura teste unitare pentru codul dvs., trebuie mai întâi să definiți o clasă de test care moștenește din unittest.TestCase. Toate cazurile de testare trebuie specificate ca metode în interiorul clasei și ar trebui să înceapă cu test_.

Notă: Dacă nu denumiți metodele ca test_, veți vedea că testele corespunzătoare nu vor fi detectate și, prin urmare, nu vor rula.

Acum să încercăm să rulăm modulul test_add de pe terminal.

$ python test_add.py

Veți vedea că nu există nicio ieșire și că niciunul dintre teste nu a rulat.

De ce este cazul?🤔

Acest lucru se datorează faptului că pentru a rula testele unitare, ar trebui să rulați unittest ca modul principal în timp ce rulați test_add.py, folosind comanda de mai jos.

$ python -m unittest test_add.py

La rularea comenzii detaliate de mai sus, vedem că toate cele trei teste au rulat cu succes.

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

OK

Cu toate acestea, va fi convenabil să rulați testele atunci când acest modul test_add este rulat, da? Să învățăm cum să o facem în secțiunea următoare.

Folosind if __name__ == ‘__main__’ pentru a rula unittest ca modul principal

Dacă doriți să rulați toate testele unitare când modulul rulează direct, puteți adăuga condiționalul.

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

Condiționalul din fragmentul de cod de mai sus îi spune interpretului Python: Dacă acest modul este rulat direct, atunci rulați codul în interior. unittest.main().

Puteți rula modulul test_add după ce adăugați cele două linii de cod de mai sus.

$ python test_add.py

▶️ Rularea directă a modulului de adăugare a testului rulează acum toate cele trei teste pe care le-am definit.

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

OK

Ieșirea de mai sus OK indică faptul că toate testele au fost executate cu succes. Cele trei puncte… indică faptul că trei teste au fost efectuate și toate au trecut.

  7 cele mai bune aplicații digitale pentru cărți de vizită (gratuite + plătite)

Acum, să modificăm valoarea de returnare așteptată test_add_1_minus7 la 8. Deoarece funcția returnează – 6 în acest caz, ar trebui să existe un test eșuat.

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

După cum se vede în rezultatul de mai jos, obținem .F., dintre cele trei teste, modelul unul dintre ele a eșuat (al doilea test), iar în traceback, obținem o AssertionError care indică – 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)

Un lucru important de reținut este că testele nu rulează neapărat în aceeași ordine în care sunt specificate în clasa de test. În exemplul de mai sus, test_add_1_minus7 este definit ca a treia metodă din clasa de testare, dar testul corespunzător a fost executat al doilea.

Rezumând

Sper că acest tutorial v-a ajutat să înțelegeți cum funcționează condiționalul if __name__ == ‘__main__’ în Python.

Iată o scurtă recapitulare a principalelor concluzii:

  • Interpretul Python setează variabila __name__ înainte de a executa scriptul Python.
  • Când rulați un modul direct, valoarea __name__ este __main__.
  • Când importați un modul într-un alt script Python, valoarea __name__ este numele modulului.
  • Puteți utiliza if __name__ == ‘__main__’ pentru a controla execuția și ce părți ale modulului rulează în timpul rulărilor directe și, respectiv, importate.

Apoi, consultați acest ghid aprofundat despre seturile Python. Învățare fericită!🎉