Forstå om __name__ == «__main__» i Python

I denne veiledningen vil du forstå funksjonaliteten og betydningen av hvis __name__ == «__main__» i Python.

Har du noen gang skummet gjennom en Python-kodebase med forskjellige moduler?

Hvis ja, ville du sannsynligvis ha kommet over om __name__ == «__main__» er betinget i en eller flere moduler. I løpet av de neste minuttene vil vi avmystifisere hva det ovennevnte betingede betyr og se på et eksempel der det kan være nyttig.

La oss begynne!

Hva er betydningen av __navn__ i Python?

I Python er en modul en .py-fil som inneholder funksjonsdefinisjoner, et sett med uttrykk som skal evalueres og mer. For eksempel, hvis vi har en fil som heter hello_world.py, refererer vi til denne som hello_world.py-filen eller hello_world-modulen.

Når du kjører en Python-modul, setter Python-tolken verdiene for noen få spesielle variabler før kjøring: __name__ er en av dem. Nøkkelen til å forstå betydningen __navn__ er å forstå hvordan import fungerer i Python.

📁 Last ned koden for denne delen her.

Gå over til mappen eksempel-1. Vi har filen module1.py. Variabelen __name__ er i navneområdet til gjeldende modul.

Denne modulen skriver ut en linje etterfulgt av verdien av variabelen __name__.

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

La oss nå kjøre modul1 fra kommandolinjen.

$ python module1.py

I utdataene ser vi at variabelen __name__ er satt til __main__.

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

Importere moduler i Python

I tillegg til å kjøre en Python-modul, vil du kanskje noen ganger bruke funksjonalitet fra en annen Python-modul inne i den gjeldende modulen. Python legger til rette for dette gjennom import.

  4 gratis verktøy for å lage animerte GIF-er av høy kvalitet

Importer lar deg gjenbruke funksjonaliteten til en annen modul – ved å importere den inn i gjeldende moduls omfang – uten å måtte skrive om koden.

Modul2.py-filen inneholder følgende. Vi har importert modul1 inne. 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 kjører module2.py og observerer utdataene.

$ python module2.py

I utgangen nedenfor:

  • Vi ser at modul1 kjøres under panseret når vi importerer den inne i modul2, og tilsvarende utgang skrives ut.
  • Men denne gangen er variabelen __name__ ikke __main__ men modul1.
  • Fordi vi kjørte modul2 direkte, er __name__-variabelen som tilsvarer modulen nå __main__.
Output

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

💡 Nøkkelidé:

– Hvis en modul kjøres direkte, er variabelen __name__ satt til lik __main__.

– Hvis en modul importeres i en annen modul, settes dens __navn__ til navnet på modulen.

Eksempel på if __name__==’__main__» i Python

I delen vil vi se et praktisk brukstilfelle av if __name__ == «__main__»-betingelsen. Vi definerer en enkel funksjon og skriver deretter enhetstester for å sjekke om funksjonen fungerer som forventet.

📁 Last ned koden og følg med.

Koden for denne delen finner du i mappen eksempel-2.

Her er add.py en Python-fil som inneholder definisjonen av funksjonen add_ab(). Funksjonen add_ab() tar inn hvilke som helst to tall og returnerer summen deres.

# example-2/add.py

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

Vi bruker Pythons unittest-modul for å teste funksjonen add_ab().

  Hva er RNG i videospill, og hvorfor kritiserer folk det?

Skrive testsaker for en Python-funksjon

Se på kodebiten nedenfor, som inneholder innholdet i test_add-modulen.

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

Koden ovenfor gjør følgende:

  • Importerer Pythons innebygde unittest-modul
  • Importerer funksjonen add_ab() fra add-modulen
  • Definerer testklassen TestAdd og et sett med testtilfeller som metoder innenfor testklassen

For å sette opp enhetstester for koden din, bør du først definere en testklasse som arver fra unittest.TestCase. Alle testtilfeller bør spesifiseres som metoder inne i klassen og bør starte med test_.

Merk: Hvis du ikke navngir metodene som test_, vil du se at de tilsvarende testene ikke vil bli oppdaget og derfor ikke kjøres.

La oss nå prøve å kjøre test_add-modulen fra terminalen.

$ python test_add.py

Du vil se at det ikke er noen utgang, og ingen av testene har kjørt.

Hvorfor er dette tilfellet?🤔

Dette er fordi for å kjøre enhetstestene, bør du kjøre unittest som hovedmodul mens du kjører test_add.py, ved å bruke kommandoen nedenfor.

$ python -m unittest test_add.py

Når vi kjører den overordnede kommandoen, ser vi at alle tre testene har kjørt vellykket.

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

OK

Det vil imidlertid være praktisk å kjøre testene når denne modulen test_add kjøres, ja? La oss lære hvordan du gjør det i neste avsnitt.

Bruke if __name__ == «__main__» for å kjøre unittest som hovedmodul

Hvis du vil kjøre alle enhetstestene når modulen kjører direkte, kan du legge til 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 kodebiten ovenfor forteller Python-tolkeren: Hvis denne modulen kjøres direkte, så kjør koden inne. unittest.main().

  Hvor mange ganger kan du bli utestengt på PS4

Du kan kjøre test_add-modulen etter å ha lagt til de to ovennevnte kodelinjene.

$ python test_add.py

▶️ Når du kjører test add-modulen direkte nå kjører alle de tre testene vi har definert.

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

OK

Ovennevnte utgang OK indikerer at alle testene ble kjørt vellykket. De tre prikkene … indikerer at tre tester ble kjørt, og alle bestått.

La oss nå endre den forventede returverdien test_add_1_minus7 til 8. Fordi funksjonen returnerer – 6 i dette tilfellet, bør det være en feilende test.

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

Som vist i utdataene nedenfor, får vi .F., av de tre testene, mislyktes mønster en av dem (den andre testen), og i tilbakesporingen får vi en AssertionError som sier – 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 viktig ting å merke seg er at testene ikke nødvendigvis kjører i samme rekkefølge som de er spesifisert i testklassen. I eksemplet ovenfor er test_add_1_minus7 definert som den tredje metoden i testklassen, men den tilsvarende testen ble kjørt på andreplass.

Oppsummering

Jeg håper denne opplæringen hjalp deg med å forstå hvordan if __name__ == «__main__»-betingelsen fungerer i Python.

Her er en rask oppsummering av de viktigste takeawayene:

  • Python-tolkeren setter variabelen __name__ før Python-skriptet kjøres.
  • Når du kjører en modul direkte, er verdien av __navn__ __main__.
  • Når du importerer en modul i et annet Python-skript, er verdien av __name__ modulnavnet.
  • Du kan bruke if __name__ == «__main__» for å kontrollere utførelse og hvilke deler av modulen som kjøres under henholdsvis direkte og importerte kjøringer.

Deretter kan du sjekke ut denne dybdeveiledningen om Python-sett. God læring!🎉