Wat doet if __name__ == "__main__":?
Wat doet de if __name__ == "__main__":
?
# Threading example
import time, thread
def myfunction(string, sleeptime, lock, *args):
while True:
lock.acquire()
time.sleep(sleeptime)
lock.release()
time.sleep(sleeptime)
if __name__ == "__main__":
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
5496
3
Wanneer de Python interpreter een bronbestand leest, doet hij twee dingen:
__name__
, en danLaten we eens kijken hoe dit werkt en hoe het verband houdt met je vraag over de
__name__
controles die we altijd zien in Python scripts. Code VoorbeeldLaten we een iets ander codevoorbeeld gebruiken om te onderzoeken hoe imports en scripts werken. Stel dat het volgende in een bestand genaamd
foo.py
staat.Speciale Variabelen
Wanneer de Python interpeter een bronbestand leest, definieert hij eerst een paar speciale variabelen. In dit geval gaat het om de
__name__
variabele. Wanneer uw module het hoofdprogramma is Als je je module (het bronbestand) als het hoofdprogramma uitvoert, bijv.zal de interpreter de hard-coded string
"__main__"
toewijzen aan de__name__
variabele, d.w.z.Wanneer uw module wordt geïmporteerd door een andere Aan de andere kant, stel dat een andere module het hoofdprogramma is en het importeert jouw module. Dit betekent dat er een verklaring als deze is in het hoofdprogramma, of in een andere module die het hoofdprogramma importeert:
In dit geval kijkt de interpreter naar de bestandsnaam van uw module,
foo.py
, haalt de.py
weg, en wijst die string toe aan uw module's__name__
variabele, d.w.z.Uitvoeren van de module's code
Nadat de speciale variabelen zijn ingesteld, voert de interpreter alle code in de module uit, één statement per keer. U wilt misschien een ander venster openen aan de zijkant met het codevoorbeeld, zodat u deze uitleg kunt volgen. Altijd
"before import"
af (zonder aanhalingstekens).math
module en wijst het toe aan een variabele genaamdmath
. Dit is equivalent aan het vervangen vanimport math
door het volgende (merk op dat__import__
een low-level functie in Python is die een string neemt en de eigenlijke import in gang zet):"before functionA"
af.def
blok uit, creëert een functie object en wijst dat functie object toe aan een variabele genaamdfunctionA
."before functionB"
af.def
-blok wordt uitgevoerd, waarbij een ander functieobject wordt aangemaakt en vervolgens wordt toegewezen aan een variabele met de naamfunctieB
."before __name__ guard"
af. Alleen als je module het hoofdprogramma is__name__
inderdaad is ingesteld op"__main__"
en het roept de twee functies aan, waarbij de strings"Function A"
en"Function B 10.0"
worden afgedrukt. Alleen wanneer uw module door een ander wordt geïmporteerd__name__
"foo"
zijn, en niet"__main__"
, en het'zal de body van deif
verklaring overslaan. Altijd"na __name__ guard"
in beide situaties afdrukken. Samenvatting Samenvattend, hier'is wat'in de twee gevallen zou worden afgedrukt:Waarom werkt het op deze manier?
Je zou je natuurlijk kunnen afvragen waarom iemand dit zou willen. Wel, soms wil je een
.py
bestand schrijven dat zowel gebruikt kan worden door andere programma's en/of modules als een module, en ook als het hoofdprogramma zelf kan worden uitgevoerd. Voorbeelden:Uw module is een bibliotheek, maar u wilt een script modus hebben waar het een aantal unit tests of een demo uitvoert.
Uw module wordt alleen gebruikt als hoofdprogramma, maar het heeft een aantal unit tests, en het test framework werkt door het importeren van
.py
bestanden zoals uw script en het uitvoeren van speciale test functies. Je wilt niet dat het probeert het script uit te voeren alleen omdat het de module importeert.Uw module wordt meestal gebruikt als een hoofdprogramma, maar het biedt ook een programmeur-vriendelijke API voor gevorderde gebruikers. Buiten deze voorbeelden, is het's elegant dat het uitvoeren van een script in Python gewoon het instellen van een paar magische variabelen is en het importeren van het script. "Running" het script is een neveneffect van het importeren van de module van het script's. Voedsel voor de geest
Vraag: Kan ik meerdere
__name__
controlerende blokken hebben? Antwoord: het'is vreemd om dat te doen, maar de taal zal'je niet tegenhouden.Stel dat het volgende in
foo2.py
staat. Wat gebeurt er als jepython foo2.py
zegt op de command-line? Waarom?__name__
check infoo3.py
verwijdert:Wanneer uw script wordt uitgevoerd door het als een commando aan de Python interpreter door te geven,
wordt alle code uitgevoerd die op inspringniveau 0 staat. Functies en klassen die gedefinieerd zijn, nou ja, gedefinieerd, maar niets van hun code wordt uitgevoerd. In tegenstelling tot andere talen, is er geen
main()
functie die automatisch wordt uitgevoerd - demain()
functie is impliciet alle code op het hoogste niveau.In dit geval is de top-level code een
if
blok.__name__
is een ingebouwde variabele die evalueert naar de naam van de huidige module. Echter, als een module direct wordt uitgevoerd (zoals inmyscript.py
hierboven), dan wordt__name__
in plaats daarvan ingesteld op de string"__main__"
. U kunt dus testen of uw script direct wordt uitgevoerd of door iets anders wordt geïmporteerd door te testenAls uw script wordt geïmporteerd in een andere module, zullen de verschillende functie en klasse definities worden geïmporteerd en de top-level code zal worden uitgevoerd, maar de code in de then-body van de
if
clausule hierboven zal niet worden uitgevoerd omdat niet aan de voorwaarde is voldaan. Als een basisvoorbeeld, beschouw de volgende twee scripts:Nu, als je de interpreter aanroept als
De uitvoer zal zijn
Als je in plaats daarvan
two.py
uitvoert:Je krijgt
Dus, als module
one
wordt geladen, is zijn__name__
gelijk aan"one"
in plaats van"__main__"
.if __name__ == "__main__"
is het deel dat wordt uitgevoerd als het script wordt uitgevoerd vanaf (zeg) de commandoregel met een commando alspython myscript.py
.