Wat doet als __name__ == “__main__”: doen?

Gegeven de volgende code, 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))

Antwoord 1, autoriteit 100%

Kort antwoord

Het is standaardcode die gebruikers beschermt tegen het per ongeluk aanroepen van het script wanneer ze dat niet van plan waren. Hier zijn enkele veelvoorkomende problemen wanneer de bewaker wordt weggelaten uit een script:

  • Als u het guardless-script in een ander script importeert (bijv. import my_script_without_a_name_eq_main_guard), dan zal het tweede script het eerste activeren om op het moment van importeren en met behulp van de opdrachtregelargumenten van het tweede script. Dit is bijna altijd een vergissing.

  • Als je een aangepaste klasse in het guardless-script hebt en deze opslaat in een augurkbestand, zal het uitpakken ervan in een ander script een import van het guardless-script activeren, met dezelfde problemen als beschreven in het vorige bullet.

Lang antwoord

Om beter te begrijpen waarom en hoe dit van belang is, moeten we een stap terug doen om te begrijpen hoe Python scripts initialiseert en hoe dit interageert met het module-importmechanisme.

Telkens wanneer de Python-interpreter een bronbestand leest, doet hij twee dingen:

  • het stelt een paar speciale variabelen in, zoals __name__, en dan

  • het voert alle code uit die in het bestand wordt gevonden.

Laten we eens kijken hoe dit werkt en hoe dit verband houdt met uw vraag over de __name__-controles die we altijd zien in Python-scripts.

Codevoorbeeld

Laten we een iets ander codevoorbeeld gebruiken om te onderzoeken hoe import en scripts werken. Stel dat het volgende in een bestand staat met de naam foo.py.

# Suppose this is foo.py.
print("before import")
import math
print("before functionA")
def functionA():
    print("Function A")
print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))
print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

Speciale variabelen

Als de Python-interpreter een bronbestand leest, definieert het eerst een paar speciale variabelen. In dit geval geven we om de variabele __name__.

Als uw module het hoofdprogramma is

Als u uw module (het bronbestand) als hoofdprogramma gebruikt, bijv.

python foo.py

de interpreter wijst de hardgecodeerde string "__main__" toe aan de variabele __name__, d.w.z.

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

Wanneer uw module door een ander wordt geïmporteerd

Aan de andere kant, stel dat een andere module het hoofdprogramma is en uw module importeert. Dit betekent dat er een statement als dit in het hoofdprogramma staat, of in een andere module die het hoofdprogramma importeert:

# Suppose this is in some other main program.
import foo

De interpreter zoekt naar uw foo.py-bestand (samen met zoeken naar een paar andere varianten), en voordat die module wordt uitgevoerd, zal het de naam "foo" van het importstatement naar de __name__ variabele, dwz

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

De modulecode uitvoeren

Nadat de speciale variabelen zijn ingesteld, voert de interpreter alle code in de module uit, één instructie tegelijk. Misschien wilt u een ander venster openen aan de zijkant met het codevoorbeeld, zodat u deze uitleg kunt volgen.

Altijd

  1. Het drukt de tekenreeks "before import" af (zonder aanhalingstekens).

  2. Het laadt de module math en wijst deze toe aan een variabele met de naam math. Dit komt overeen met het vervangen van import math door het volgende (merk op dat __import__ een functie op laag niveau is in Python die een string nodig heeft en de daadwerkelijke import activeert):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. Het drukt de tekenreeks "before functionA" af.

  2. Het voert het blok def uit, maakt een functieobject en wijst dat functieobject vervolgens toe aan een variabele met de naam functionA.

  3. Het drukt de tekenreeks "before functionB" af.

  4. Het voert het tweede def-blok uit, creëert een ander functieobject en wijst het vervolgens toe aan een variabele met de naam functionB.

  5. Het drukt de string "before __name__ guard" af.

Alleen als uw module het hoofdprogramma is

  1. Als uw module het hoofdprogramma is, zal het zien dat __name__ inderdaad is ingesteld op "__main__" en het roept de twee functies aan en drukt de strings "Function A" en "Function B 10.0".

Alleen wanneer uw module door een ander is geïmporteerd

  1. (in plaats daarvan) Als uw module niet het hoofdprogramma is maar door een ander is geïmporteerd, dan is __name__ "foo" , niet "__main__", en het zal de hoofdtekst van de if-instructie overslaan.

Altijd

  1. In beide situaties wordt de string "after __name__ guard" afgedrukt.

Samenvatting

Samengevat, dit is wat er in de twee gevallen zou worden afgedrukt:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

Waarom werkt het op deze manier?

Je kunt je natuurlijk afvragen waarom iemand dit zou willen. Welnu, soms wil je een .py-bestand schrijven dat zowel door andere programma’s en/of modules als module kan worden gebruikt, en dat ook als hoofdprogramma zelf kan worden uitgevoerd. Voorbeelden:

  • Uw module is een bibliotheek, maar u wilt een scriptmodus hebben waarin enkele unittests of een demo worden uitgevoerd.

  • Je module wordt alleen als hoofdprogramma gebruikt, maar er zijn enkele unit-tests, en het testframework werkt door .py-bestanden zoals je script te importeren en speciale testfuncties uit te voeren. Je wilt niet dat het het script probeert uit te voeren alleen omdat het de module importeert.

  • Uw module wordt meestal gebruikt als hoofdprogramma, maar biedt ook een programmeervriendelijke API voor gevorderde gebruikers.

Naast deze voorbeelden is het elegant dat het uitvoeren van een script in Python slechts het instellen van een paar magische variabelen is en het importeren van het script. “Hardlopen” het script is een neveneffect van het importeren van de scriptmodule.

Voedsel tot nadenken

  • Vraag: kan ik meerdere __name__ controleblokken hebben? Antwoord: het is vreemd om dat te doen, maar de taal houdt je niet tegen.

  • Stel dat het volgende in foo2.py staat. Wat gebeurt er als je python foo2.py zegt op de opdrachtregel? Waarom?

# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")
def functionB():
    print("b")
print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
  • Bedenk nu wat er zal gebeuren als je de __name__ check in foo3.py verwijdert:
# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters
def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")
def functionB():
    print("b")
print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • Wat doet dit als het als script wordt gebruikt? Wanneer geïmporteerd als module?
# Suppose this is in foo4.py
__name__ = "__main__"
def bar():
    print("bar")
print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")

Antwoord 2, autoriteit 26%

Als je script wordt uitgevoerd door het als commando door te geven aan de Python-interpreter,

python myscript.py

alle code op inspringniveau 0 wordt uitgevoerd. Functies en klassen die zijn gedefinieerd, zijn, nou ja, gedefinieerd, maar geen van hun code wordt uitgevoerd. In tegenstelling tot andere talen is er geen functie main() die automatisch wordt uitgevoerd – de functie main() is impliciet alle code op het hoogste niveau.

In dit geval is de code op het hoogste niveau een if-blok. __name__ is een ingebouwde variabele die evalueert naar de naam van de huidige module. Als een module echter rechtstreeks wordt uitgevoerd (zoals in myscript.py hierboven), dan wordt __name__ in plaats daarvan ingesteld op de tekenreeks "__main__" . U kunt dus testen of uw script rechtstreeks wordt uitgevoerd of door iets anders wordt geïmporteerd door te testen

if __name__ == "__main__":
    ...

Als uw script in een andere module wordt geïmporteerd, worden de verschillende functie- en klassedefinities geïmporteerd en wordt de code op het hoogste niveau uitgevoerd, maar de code in de then-body van de if bovenstaande clausule wordt niet uitgevoerd omdat niet aan de voorwaarde is voldaan. Beschouw als basisvoorbeeld de volgende twee scripts:

# file one.py
def func():
    print("func() in one.py")
print("top-level in one.py")
if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one
print("top-level in two.py")
one.func()
if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Als u nu de interpreter aanroept als

python one.py

De uitvoer zal zijn

top-level in one.py
one.py is being run directly

Als u in plaats daarvan two.py uitvoert:

python two.py

Je krijgt

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

Dus, wanneer module one wordt geladen, is de __name__ gelijk aan "one" in plaats van "__main__" .


Antwoord 3, autoriteit 10%

De eenvoudigste verklaring voor de variabele __name__ (imho) is de volgende:

Maak de volgende bestanden.

# a.py
import b

en

# b.py
print "Hello World from %s!" % __name__
if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Als u ze uitvoert, krijgt u deze uitvoer:

$ python a.py
Hello World from b!

Zoals je kunt zien, stelt Python, wanneer een module wordt geïmporteerd, globals()['__name__'] in deze module in op de naam van de module. Ook wordt bij het importeren alle code in de module uitgevoerd. Aangezien de if-instructie evalueert tot False wordt dit deel niet uitgevoerd.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

Zoals je kunt zien, stelt Python, wanneer een bestand wordt uitgevoerd, globals()['__name__'] in dit bestand in op "__main__". Deze keer evalueert de if-instructie tot True en wordt uitgevoerd.


Antwoord 4, autoriteit 7%

Wat doet de if __name__ == "__main__":?

Om de basis te schetsen:

  • De globale variabele, __name__, in de module die het toegangspunt is tot uw programma, is '__main__'. Anders is het de naam waarmee u de module importeert.

  • Dus de code onder het if-blok wordt alleen uitgevoerd als de module het toegangspunt tot je programma is.

  • Hiermee kan de code in de module worden geïmporteerd door andere modules, zonder het codeblok eronder uit te voeren bij het importeren.


Waarom hebben we dit nodig?

Uw code ontwikkelen en testen

Stel dat je een Python-script schrijft dat is ontworpen om als module te worden gebruikt:

def do_important():
    """This function does something very important"""

U zou de module kunnen testen door deze aanroep van de functie onderaan toe te voegen:

do_important()

en het uitvoeren (op een opdrachtprompt) met iets als:

~$ python important.py

Het probleem

Als u de module echter naar een ander script wilt importeren:

import important

Bij het importeren zou de functie do_important worden aangeroepen, dus je zou waarschijnlijk je functieaanroep, do_important(), onderaan als commentaar plaatsen.

# do_important() # I must remember to uncomment to execute this!

En dan moet je onthouden of je al dan niet commentaar hebt gegeven op je testfunctie-aanroep. En deze extra complexiteit zou betekenen dat u het waarschijnlijk vergeet, waardoor uw ontwikkelingsproces lastiger wordt.

Een betere manier

De variabele __name__ verwijst naar de naamruimte waar de Python-interpreter zich op dat moment bevindt.

Binnen een geïmporteerde module is dit de naam van die module.

Maar binnen de primaire module (of een interactieve Python-sessie, d.w.z. de Read, Eval, Print Loop of REPL van de interpreter) voer je alles uit vanuit zijn "__main__".

Dus als u controleert voordat u het uitvoert:

if __name__ == "__main__":
    do_important()

Met het bovenstaande wordt uw code alleen uitgevoerd als u deze als de primaire module uitvoert (of opzettelijk vanuit een ander script aanroept).

Een nog betere manier

Er is echter een Pythonische manier om dit te verbeteren.

Wat als we dit bedrijfsproces van buiten de module willen laten lopen?

Als we de code die we willen gebruiken tijdens het ontwikkelen en testen in een functie als deze plaatsen en dan onze controle uitvoeren op '__main__' onmiddellijk daarna:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()
# Here's our payoff idiom!
if __name__ == '__main__':
    main()

We hebben nu een laatste functie voor het einde van onze module die wordt uitgevoerd als we de module als de primaire module uitvoeren.

Hiermee kunnen de module en zijn functies en klassen worden geïmporteerd in andere scripts zonder de functie main uit te voeren, en kan de module (en zijn functies en klassen) ook worden aangeroepen tijdens het uitvoeren van een andere '__main__' module, bijv.

import important
important.main()

Dit idioom is ook te vinden in de Python-documentatie in een uitleg van de __main__ module. In die tekst staat:

Deze module vertegenwoordigt het (anders anonieme) bereik waarin de
het hoofdprogramma van de interpreter voert opdrachten uit die gelezen worden van
standaardinvoer, vanuit een scriptbestand of vanuit een interactieve prompt. Het
is deze omgeving waarin de idiomatische strofe ‘voorwaardelijk schrift’
zorgt ervoor dat een script wordt uitgevoerd:

if __name__ == '__main__':
    main()

Antwoord 5, autoriteit 2%

if __name__ == "__main__" is het deel dat wordt uitgevoerd wanneer het script wordt uitgevoerd vanaf (bijvoorbeeld) de opdrachtregel met een opdracht als python myscript.py.


Antwoord 6

Wat doet if __name__ == "__main__":?

__name__ is een globale variabele (in Python betekent global eigenlijk op het moduleniveau ) die in alle naamruimten bestaat. Het is meestal de naam van de module (als een str type).

Als het enige speciale geval echter, in welk Python-proces je ook draait, zoals in mycode.py:

python mycode.py

de anders anonieme globale naamruimte krijgt de waarde '__main__' toegewezen aan zijn __name__.

Dus inclusief de laatste regels

if __name__ == '__main__':
    main()
  • aan het einde van uw mycode.py-script,
  • wanneer het de primaire ingangsmodule is die wordt uitgevoerd door een Python-proces,

zal ervoor zorgen dat de uniek gedefinieerde main-functie van uw script wordt uitgevoerd.

Een ander voordeel van het gebruik van deze constructie: u kunt uw code ook als module in een ander script importeren en vervolgens de hoofdfunctie uitvoeren als en wanneer uw programma dat beslist:

import mycode
# ... any amount of other code
mycode.main()

Antwoord 7

Er zijn hier veel verschillende opvattingen over de mechanica van de code in kwestie, het “Hoe”, maar voor mij was niets logisch totdat ik het “Waarom” begreep. Dit zou vooral handig moeten zijn voor nieuwe programmeurs.

Neem bestand “ab.py”:

def a():
    print('A function in ab file');
a()

En een tweede bestand “xy.py”:

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

Wat doet deze code eigenlijk?

Wanneer u xy.py uitvoert, import ab. Het importstatement voert de module direct bij het importeren uit, dus de bewerkingen van ab worden uitgevoerd vóór de rest van de xy‘s. Eenmaal klaar met ab, gaat het verder met xy.

De interpreter houdt bij welke scripts draaien met __name__. Wanneer je een script uitvoert – ongeacht hoe je het genoemd hebt – noemt de interpreter het "__main__", waardoor het het master- of ‘home’-script wordt waarnaar wordt teruggekeerd na het uitvoeren van een extern script.

Elk ander script dat wordt aangeroepen vanuit dit "__main__"-script krijgt zijn bestandsnaam toegewezen als zijn __name__ (bijv. __name__ == "ab.py"). Daarom is de regel if __name__ == "__main__": de test van de interpreter om te bepalen of het het ‘home’-script interpreteert/parseert dat in eerste instantie werd uitgevoerd, of dat het tijdelijk naar een ander (extern) gluurt script. Dit geeft de programmeur de flexibiliteit om het script zich anders te laten gedragen als het direct wordt uitgevoerd of extern wordt aangeroepen.

Laten we de bovenstaande code eens doornemen om te begrijpen wat er gebeurt, waarbij we ons eerst concentreren op de niet-ingesprongen regels en de volgorde waarin ze in de scripts verschijnen. Onthoud dat functie- of def-blokken niets uit zichzelf doen totdat ze worden aangeroepen. Wat de tolk zou zeggen als hij in zichzelf mompelde:

  • Open xy.py als het ‘home’-bestand; noem het "__main__" in de variabele __name__.
  • Importeer en open bestand met de __name__ == "ab.py".
  • O, een functie. Dat zal ik onthouden.
  • Ok, functie a(); Dat heb ik net geleerd. Afdrukken van ‘Een functie in ab-bestand‘.
  • Einde van bestand; terug naar "__main__"!
  • O, een functie. Dat zal ik onthouden.
  • Nog een.
  • Functie x(); ok, afdrukken van ‘randtaak: kan nuttig zijn in andere projecten‘.
  • Wat is dit? Een if-statement. Welnu, aan de voorwaarde is voldaan (de variabele __name__ is ingesteld op "__main__"), dus ik voer de main() in functie en print ‘hoofdfunctie: dit is waar de actie is‘.

De onderste twee regels betekenen: “Als dit het "__main__" of ‘home’ script is, voer dan de functie uit met de naam main()“. Daarom zie je een def main():-blok bovenaan, dat de hoofdstroom van de functionaliteit van het script bevat.

Waarom dit implementeren?

Weet je nog wat ik eerder zei over importstatements? Wanneer u een module importeert, ‘herkent’ deze deze niet alleen en wacht op verdere instructies – het voert eigenlijk alle uitvoerbare bewerkingen uit die in het script zijn opgenomen. Dus als je het vlees van je script in de functie main() plaatst, wordt het effectief in quarantaine geplaatst, waardoor het geïsoleerd wordt zodat het niet onmiddellijk wordt uitgevoerd wanneer het door een ander script wordt geïmporteerd.

Nogmaals, er zullen uitzonderingen zijn, maar het is gebruikelijk dat main() meestal niet extern wordt aangeroepen. Dus je vraagt ​​je misschien nog iets af: als we main() niet aanroepen, waarom roepen we dan het script aan? Dat komt omdat veel mensen hun scripts structureren met zelfstandige functies die zijn gebouwd om onafhankelijk van de rest van de code in het bestand te worden uitgevoerd. Ze worden dan later ergens anders in de hoofdtekst van het script genoemd. Dat brengt me bij dit:

Maar de code werkt ook zonder

Ja, dat klopt. Deze afzonderlijke functies kunnen worden aangeroepen vanuit een in-line script dat niet is opgenomen in een functie main(). Als je gewend bent (zoals ik, in mijn vroege leerstadia van programmeren) om in-line scripts te bouwen die precies doen wat je nodig hebt, en je zult het opnieuw proberen uit te zoeken als je die bewerking ooit weer nodig hebt. Nou, je bent niet gewend aan dit soort interne structuur van je code, omdat het ingewikkelder is om te bouwen en niet zo intuïtief om te lezen.

Maar dat is een script waarvan de functies waarschijnlijk niet extern kunnen worden aangeroepen, want als het dat wel zou doen, zou het onmiddellijk beginnen met het berekenen en toewijzen van variabelen. En de kans is groot dat als je een functie probeert te hergebruiken, je nieuwe script nauw genoeg verwant is aan het oude, dat er conflicterende variabelen zullen zijn.

Door onafhankelijke functies op te splitsen, krijgt u de mogelijkheid om uw eerdere werk opnieuw te gebruiken door ze in een ander script aan te roepen. “example.py” kan bijvoorbeeld “xy.py” importeren en x() aanroepen, gebruikmakend van de ‘x’-functie van “xy.py”. (Misschien is het een hoofdletter van het derde woord van een gegeven tekstreeks, een NumPy-array maken van een lijst met getallen en deze kwadrateren, of een 3D-oppervlak ontwijken. De mogelijkheden zijn onbeperkt.)

(Terzijde: deze vraag bevat een antwoord van @kindall dat uiteindelijk heeft me geholpen te begrijpen – het waarom, niet het hoe. Helaas is het gemarkeerd als een duplicaat van deze, wat volgens mij een vergissing is.)


Antwoord 8

Als er bepaalde statements in onze module (M.py) zijn die we willen uitvoeren wanneer deze als main wordt uitgevoerd (niet geïmporteerd), kunnen we die statements (testcases) plaatsen , print statements) onder dit if blok.

Standaard (wanneer module draait als main, niet geïmporteerd) is de __name__ variabele ingesteld op "__main__", en wanneer deze wordt geïmporteerd de __name__ variabele krijgt een andere waarde, hoogstwaarschijnlijk de naam van de module ('M').
Dit is handig bij het samen uitvoeren van verschillende varianten van een module en het scheiden van hun specifieke invoer & output-statements en ook of er testgevallen zijn.

Kortom, gebruik dit ‘if __name__ == "main" ‘ blok om te voorkomen dat (bepaalde) code wordt uitgevoerd wanneer de module wordt geïmporteerd.


Antwoord 9

Simpel gezegd, __name__ is een variabele die voor elk script is gedefinieerd en die bepaalt of het script wordt uitgevoerd als de hoofdmodule of als een geïmporteerde module.

Dus als we twee scripts hebben;

#script1.py
print "Script 1's name: {}".format(__name__)

en

#script2.py
import script1
print "Script 2's name: {}".format(__name__)

De uitvoer van het uitvoeren van script1 is

Script 1's name: __main__

En de uitvoer van het uitvoeren van script2 is:

Script1's name is script1
Script 2's name: __main__

Zoals je kunt zien, vertelt __name__ ons welke code de ‘hoofd’-module is.
Dit is geweldig, omdat je gewoon code kunt schrijven en je geen zorgen hoeft te maken over structurele problemen zoals in C/C++, waar, als een bestand geen ‘hoofd’-functie implementeert, het niet als een uitvoerbaar bestand kan worden gecompileerd en als dat wel het geval is, het kan dan niet als bibliotheek worden gebruikt.

Stel dat je een Python-script schrijft dat iets geweldigs doet en je implementeert een massa functies die nuttig zijn voor andere doeleinden. Als ik ze wil gebruiken, kan ik gewoon je script importeren en gebruiken zonder je programma uit te voeren (aangezien je code alleen wordt uitgevoerd binnen de context if __name__ == "__main__":). Terwijl je in C/C++ die stukjes zou moeten verdelen in een aparte module die dan het bestand bevat. Stel je de situatie hieronder voor;

Gecompliceerd importeren in C

De pijlen zijn importlinks. Voor drie modules die elk de code van de vorige modules proberen op te nemen, zijn er zes bestanden (negen, de implementatiebestanden meegerekend) en vijf links. Dit maakt het moeilijk om andere code in een C-project op te nemen, tenzij deze specifiek als bibliotheek is gecompileerd. Stel je het nu voor voor Python:

Elegant importeren in Python

Je schrijft een module, en als iemand je code wil gebruiken, importeren ze die gewoon en de variabele __name__ kan helpen om het uitvoerbare gedeelte van het programma te scheiden van het bibliotheekgedeelte.


Antwoord 10

Laten we het antwoord op een meer abstracte manier bekijken:

Stel dat we deze code hebben in x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

Blokken A en B worden uitgevoerd wanneer we x.py gebruiken.

Maar blok A (en niet B) wordt uitgevoerd wanneer we een andere module gebruiken, bijvoorbeeld y.py, waarin x.py wordt geïmporteerd en de code wordt vanaf daar uitgevoerd (zoals wanneer een functie in x.py wordt aangeroepen vanuit y.py).


Antwoord 11

Ik heb zoveel gelezen tijdens de antwoorden op deze pagina. Ik zou zeggen, als je het weet, zul je die antwoorden zeker begrijpen, anders ben je nog steeds in de war.

Om kort te zijn, je moet een aantal punten weten:

  1. import a actie voert eigenlijk alles uit wat kan worden uitgevoerd in a.py, wat betekent dat elke regel in a.py

  2. Vanwege punt 1 wil je misschien niet dat alles in a.py wordt uitgevoerd bij het importeren

  3. Om het probleem in punt 2 op te lossen, kunt u met python een conditiecontrole uitvoeren

  4. __name__ is een impliciete variabele in alle .py-modules:

  • wanneer a.py wordt imported, wordt de waarde van __name__ van de module a.py ingesteld naar de bestandsnaam "a"
  • wanneer a.py rechtstreeks wordt uitgevoerd met "python a.py", wordt de waarde van __name__ ingesteld op een tekenreeks __main__
  1. Weet je op basis van het mechanisme hoe python de variabele __name__ voor elke module instelt, hoe je punt 3 kunt bereiken? Het antwoord is vrij eenvoudig, toch? Zet een if-voorwaarde: if __name__ == "__main__": // do A
  • dan zal python a.py het onderdeel // do A
  • uitvoeren

  • en import a slaan het deel // do A
  • over

  1. Je kunt zelfs if __name__ == "a" plaatsen, afhankelijk van je functionele behoefte, maar doe dat zelden

Het belangrijkste waar python speciaal in is, is punt 4! De rest is gewoon basislogica.


Antwoord 12

Als je Python interactief uitvoert, krijgt de lokale variabele __name__ de waarde __main__ toegewezen. Evenzo, wanneer u een Python-module vanaf de opdrachtregel uitvoert, in plaats van deze in een andere module te importeren, wordt aan het kenmerk __name__ de waarde __main__ toegewezen in plaats van de werkelijke naam van de module. Op deze manier kunnen modules naar hun eigen __name__ waarde kijken om voor zichzelf te bepalen hoe ze worden gebruikt, als ondersteuning voor een ander programma of als de hoofdtoepassing die vanaf de opdrachtregel wordt uitgevoerd. Het volgende idioom is dus vrij gebruikelijk in Python-modules:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.

Antwoord 13

Overweeg:

if __name__ == "__main__":
    main()

Het controleert of het kenmerk __name__ van het Python-script "__main__" is. Met andere woorden, als het programma zelf wordt uitgevoerd, is het attribuut __main__, dus het programma wordt uitgevoerd (in dit geval de functie main()).

Als uw Python-script echter door een module wordt gebruikt, wordt elke code buiten de if-instructie uitgevoerd, dus if \__name__ == "\__main__" wordt alleen gebruikt om te controleren of het programma als module wordt gebruikt of niet, en beslist daarom of de code moet worden uitgevoerd.


Antwoord 14

De code onder if __name__ == '__main__': wordt alleen uitgevoerd als de module wordt aangeroepen als een script.

Beschouw als voorbeeld de volgende module my_test_module.py:

# my_test_module.py
print('This is going to be printed out, no matter what')
if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

1e mogelijkheid: importeer my_test_module.py in een andere module

# main.py
import my_test_module
if __name__ == '__main__':
    print('Hello from main.py')

Als je nu main.py aanroept:

python main.py 
>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Merk op dat alleen het print()-statement op het hoogste niveau in my_test_module wordt uitgevoerd.


2e mogelijkheid: roep my_test_module.py op als een script

Als u nu my_test_module.py uitvoert als een Python-script, worden beide print()-instructies uitgevoerd:

python my_test_module.py
>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

Voor een uitgebreidere uitleg kun je lezen Wat doet if __name__ == '__main__' doen in Python.


Antwoord 15

Alvorens iets uit te leggen over if __name__ == '__main__' is het belangrijk om te begrijpen wat __name__ is en wat het doet.

Wat is __name__?

__name__ is een DunderAlias – kan worden gezien als een globale variabele (toegankelijk vanuit modules) en werkt op dezelfde manier als global.

Het is een string (algemeen zoals hierboven vermeld) zoals aangegeven door type(__name__) (die <class 'str'> oplevert), en is een ingebouwde standaard voor zowel Python 3 als Python 2-versies.

Waar:

Het kan niet alleen in scripts worden gebruikt, maar is ook te vinden in zowel de interpreter als modules/pakketten.

Tolk:

>>> print(__name__)
__main__
>>>

Script:

test_file.py:

print(__name__)

Resulterend in __main__

Module of pakket:

een bestand.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Resulterend in somefile

Merk op dat bij gebruik in een pakket of module, __name__ de naam van het bestand aanneemt. Het pad van het eigenlijke module- of pakketpad wordt niet gegeven, maar heeft zijn eigen DunderAlias ​​__file__, die dit mogelijk maakt.

Je zou moeten zien dat, waar __name__, waar het het hoofdbestand (of programma) is, altijd __main__ wordt geretourneerd, en als het is een module/pakket, of iets dat op een ander Python-script draait, retourneert de naam van het bestand waar het vandaan komt.

Oefen:

Een variabele zijn betekent dat de waarde ervan kan worden overschreven (“kan” betekent niet “zou moeten”), het overschrijven van de waarde van __name__ zal resulteren in een gebrek aan leesbaarheid. Dus doe het niet, om welke reden dan ook. Als je een variabele nodig hebt, definieer dan een nieuwe variabele.

Er wordt altijd aangenomen dat de waarde van __name__ __main__ is of de naam van het bestand. Nogmaals, het wijzigen van deze standaardwaarde zal meer verwarring veroorzaken dat het goed zal doen, wat later problemen veroorzaakt.

voorbeeld:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

Het wordt in het algemeen als een goede gewoonte beschouwd om de if __name__ == '__main__' in scripts op te nemen.

Nu antwoorden if __name__ == '__main__':

Nu weten we het gedrag van __name__ dingen worden duidelijker:

Een if is een flow control-instructie die het codeblok bevat, wordt uitgevoerd als de opgegeven waarde waar is. We hebben gezien dat __name__ ofwel:
__main__ of de bestandsnaam waaruit het is geïmporteerd.

Dit betekent dat als __name__ gelijk is aan __main__, het bestand het hoofdbestand moet zijn en daadwerkelijk moet worden uitgevoerd (of het is de interpreter), niet een module of pakket geïmporteerd in het script.

Als __name__ inderdaad de waarde van __main__ aanneemt, wordt alles wat in dat codeblok staat uitgevoerd.

Dit vertelt ons dat als het bestand dat wordt uitgevoerd het hoofdbestand is (of u rechtstreeks vanuit de interpreter uitvoert), die voorwaarde moet worden uitgevoerd. Als het een pakket is, zou het dat niet moeten zijn, en de waarde zal niet __main__ zijn.

Modules:

__name__ kan ook in modules worden gebruikt om de naam van een module te definiëren

Varianten:

Het is ook mogelijk om andere, minder gebruikelijke maar nuttige dingen te doen met __name__, sommige zal ik hier laten zien:

Alleen uitvoeren als het bestand een module of pakket is:

if __name__ != '__main__':
    # Do some useful things 

Een voorwaarde uitvoeren als het bestand het hoofdbestand is en een andere als dit niet het geval is:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

Je kunt het ook gebruiken om uitvoerbare helpfuncties/hulpprogramma’s op pakketten en modules te bieden zonder het uitgebreide gebruik van bibliotheken.

Het staat ook toe dat modules vanaf de opdrachtregel als hoofdscripts worden uitgevoerd, wat ook erg handig kan zijn.


Antwoord 16

Ik denk dat het het beste is om het antwoord uitgebreid en in eenvoudige bewoordingen te bespreken:

__name__: Elke module in Python heeft een speciaal attribuut genaamd __name__.
Het is een ingebouwde variabele die de naam van de module retourneert.

__main__: Net als andere programmeertalen heeft Python ook een invoerpunt voor de uitvoering, d.w.z. main. '__main__' is de naam van het bereik waarin de code op het hoogste niveau wordt uitgevoerd. In principe heb je twee manieren om een ​​Python-module te gebruiken: voer het rechtstreeks uit als een script of importeer het. Wanneer een module als een script wordt uitgevoerd, wordt de __name__ ingesteld op __main__.

De waarde van het __name__ attribuut wordt dus ingesteld op __main__ wanneer de module als het hoofdprogramma wordt uitgevoerd. Anders wordt de waarde van __name__ ingesteld om de naam van de module te bevatten.


Antwoord 17

Het is speciaal voor wanneer een Python-bestand wordt aangeroepen vanaf de opdrachtregel. Dit wordt meestal gebruikt om een ​​"main()" functie of voer andere geschikte opstartcode uit, zoals bijvoorbeeld het afhandelen van commandoregelargumenten.

Het kan op verschillende manieren worden geschreven. Een andere is:

def some_function_for_instance_main():
    dosomething()
__name__ == '__main__' and some_function_for_instance_main()

Ik zeg niet dat je dit in productiecode moet gebruiken, maar het dient om te illustreren dat er niets “magisch” is. over if __name__ == '__main__'.

Het is gewoon een conventie voor het aanroepen van een hoofdfunctie in Python-bestanden.


Antwoord 18

Er zijn een aantal variabelen die het systeem (Python-interpreter) biedt voor bronbestanden (modules). U kunt hun waarden op elk gewenst moment ophalen, dus laten we ons concentreren op de __name__ variabele/attribuut:

Wanneer Python een broncodebestand laadt, voert het alle code uit die erin wordt gevonden. (Merk op dat het niet alle methoden en functies aanroept die in het bestand zijn gedefinieerd, maar het definieert ze wel.)

Voordat de interpreter het broncodebestand uitvoert, definieert het echter een paar speciale variabelen voor dat bestand; __name__ is een van die speciale variabelen die Python automatisch definieert voor elk broncodebestand.

Als Python dit broncodebestand laadt als het hoofdprogramma (dwz het bestand dat u uitvoert), dan stelt het de speciale __name__ variabele voor dit bestand in op een waarde “__main__” .

Als dit wordt geïmporteerd uit een andere module, wordt __name__ ingesteld op de naam van die module.

Dus, in jouw voorbeeld gedeeltelijk:

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

betekent dat het codeblok:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

wordt alleen uitgevoerd als u de module rechtstreeks uitvoert; het codeblok wordt niet uitgevoerd als een andere module het aanroept/importeert omdat de waarde van __name__ in dat specifieke geval niet gelijk zal zijn aan “main“.

Hopelijk helpt dit.


Antwoord 19

if __name__ == "__main__": is in feite de scriptomgeving op het hoogste niveau, en het specificeert de interpreter die (‘Ik heb de hoogste prioriteit om als eerste te worden uitgevoerd’).

'__main__' is de naam van het bereik waarin de code op het hoogste niveau wordt uitgevoerd. De __name__ van een module is gelijk aan '__main__' wanneer deze wordt gelezen vanuit standaardinvoer, een script of vanaf een interactieve prompt.

if __name__ == "__main__":
    # Execute only if run as a script
    main()

Antwoord 20

Overweeg:

print __name__

De uitvoer voor het bovenstaande is __main__.

if __name__ == "__main__":
  print "direct method"

De bovenstaande verklaring is waar en drukt “directe methode” af. Stel dat als ze deze klasse in een andere klasse hebben geïmporteerd, er geen “directe methode” wordt afgedrukt, omdat tijdens het importeren __name__ equal to "first model name".


Antwoord 21

Je kunt het bestand zowel bruikbaar maken als een script als een importeerbare module.

fibo.py (een module met de naam fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()
# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Referentie: https://docs.python.org/3.5/tutorial/modules. html


Antwoord 22

De reden voor

if __name__ == "__main__":
    main()

is voornamelijk om de importvergrendeling problemen die zouden ontstaan ​​als code rechtstreeks geïmporteerd is. U wilt dat main() wordt uitgevoerd als uw bestand rechtstreeks is aangeroepen (dat is het geval __name__ == "__main__"), maar als uw code is geïmporteerd, moet de importeur voer uw code in vanuit de echte hoofdmodule om problemen met importvergrendeling te voorkomen.

Een neveneffect is dat u zich automatisch aanmeldt bij een methodologie die meerdere toegangspunten ondersteunt. U kunt uw programma uitvoeren met main() als startpunt, maar dat hoeft niet. Terwijl setup.py main() verwacht, gebruiken andere tools alternatieve toegangspunten. Om uw bestand bijvoorbeeld uit te voeren als een gunicorn-proces, definieert u een app()-functie in plaats van een main(). Net als bij setup.py, importeert gunicorn uw code, zodat u niet wilt dat deze iets doet terwijl deze wordt geïmporteerd (vanwege het probleem met de importvergrendeling).


Antwoord 23

Elke module in python heeft een attribuut genaamd __name__. De waarde van het kenmerk __name__ is __main__ wanneer de module rechtstreeks wordt uitgevoerd, zoals python my_module.py. Anders (zoals wanneer je zegt import my_module) is de waarde van __name__ de naam van de module.

Klein voorbeeld om in het kort uit te leggen.

#Script test.py
apple = 42
def hello_world():
    print("I am inside hello_world")
if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

We kunnen dit direct uitvoeren als

python test.py  

Uitvoer

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

Stel nu dat we bovenstaand script aanroepen vanuit een ander script

#script external_calling.py
import test
print(test.apple)
test.hello_world()
print(test.__name__)

Wanneer u dit uitvoert

python external_calling.py

Uitvoer

42
I am inside hello_world
test

Het bovenstaande spreekt dus voor zich dat wanneer u test aanroept vanuit een ander script, de lus __name__ in test.py niet wordt uitgevoerd.


Antwoord 24

Dit antwoord is bedoeld voor Java-programmeurs die Python leren.
Elk Java-bestand bevat meestal één openbare klasse. Je kunt die klasse op twee manieren gebruiken:

  1. Bel de klas vanuit andere bestanden. Je hoeft het alleen maar te importeren in het aanroepprogramma.

  2. Laat de klas stand-alone uitvoeren voor testdoeleinden.

Voor het laatste geval moet de klasse een openbare statische void main()-methode bevatten. In Python wordt dit doel gediend door het globaal gedefinieerde label '__main__'.


Antwoord 25

Als dit .py-bestand wordt geïmporteerd door andere .py-bestanden, wordt de code onder “het if-statement” niet uitgevoerd.

Als deze .py wordt uitgevoerd door python this_py.py onder shell, of dubbelklikt in Windows. de code onder “het if-statement” wordt uitgevoerd.

Het is meestal geschreven om te testen.


Antwoord 26

Als de python-interpreter een bepaalde module uitvoert, heeft de globale variabele __name__ de waarde "__main__"

  def a():
      print("a")
  def b():
      print("b")
  if __name__ == "__main__": 
          print ("you can see me" )
          a()
  else: 
          print ("You can't see me")
          b()

Wanneer je dit script uitvoert, wordt afgedrukt je kunt me zien

een

Als u dit bestand importeert, zegt u A naar bestand B en voert u het bestand B uit en if __name__ == "__main__" in bestand A wordt onwaar, dus het wordt afgedrukt U kunt het niet zien ik

b


Antwoord 27

if naam == ‘hoofd‘:

We zien of __name__ == '__main__': heel vaak.

Het controleert of een module wordt geïmporteerd of niet.

Met andere woorden, de code in het if-blok wordt alleen uitgevoerd als de code direct wordt uitgevoerd. Hier betekent directly not imported.

Laten we eens kijken wat het doet met een eenvoudige code die de naam van de module afdrukt:

# test.py
def test():
   print('test module name=%s' %(__name__))
if __name__ == '__main__':
   print('call test()')
   test()

Als we de code rechtstreeks uitvoeren via python test.py, is de modulenaam __main__:

call test()
test module name=__main__

Antwoord 28

In eenvoudige bewoordingen:

De code die je ziet onder if __name__ == "__main__": wordt alleen aangeroepen als je python-bestand wordt uitgevoerd als "python example1.py".

Als u echter uw python-bestand ‘example1.py’ als module wilt importeren om met een ander python-bestand te werken, zegt u ‘example2.py’, de code onder if __name__ == "__main__": wordt niet uitgevoerd of heeft geen effect.


Antwoord 29

Alle antwoorden hebben de functionaliteit vrijwel verklaard. Maar ik zal een voorbeeld geven van het gebruik ervan, wat kan helpen om het concept verder te verduidelijken.

Stel dat je twee Python-bestanden hebt, a.py en b.py. Nu importeert a.py b.py. We voeren het a.py-bestand uit, waar eerst de code “import b.py” wordt uitgevoerd. Voordat de rest van de a.py-code wordt uitgevoerd, moet de code in het bestand b.py volledig worden uitgevoerd.

In de b.py-code is er een code die exclusief is voor dat bestand b.py en we willen geen ander bestand (anders dan het b.py-bestand), dat het b.py-bestand heeft geïmporteerd, om voer het uit.

Dus dat is wat deze regel code controleert. Als het het hoofdbestand is (d.w.z. b.py) dat de code uitvoert, wat in dit geval niet het geval is (a.py is het hoofdbestand dat wordt uitgevoerd), dan wordt alleen de code uitgevoerd.


Antwoord 30

Maak een bestand, a.py:

print(__name__) # It will print out __main__

__name__ is altijd gelijk aan __main__ wanneer dat bestand direct wordt uitgevoerd om aan te geven dat dit het hoofdbestand is.

Maak een ander bestand, b.py, in dezelfde map:

import a  # Prints a

Voer het uit. Het zal a afdrukken, d.w.z. de naam van het bestand dat is geïmporteerd.

Dus, om twee verschillende gedragingen van hetzelfde bestand te laten zien, is dit een veelgebruikte truc:

# Code to be run when imported into another python file
if __name__ == '__main__':
    # Code to be run only when run directly

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes