Biorąc pod uwagę następujący kod, co to if __name__ == "__main__":
robi?
# 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))
python
namespaces
main
python-module
idioms
Oddany
źródło
źródło
if __name__ == "__main__":
warunek blokowania jest przestarzały / nieaktualny aż do Pythona 3? Znalazłem informacje, które to potwierdzają.Odpowiedzi:
Ilekroć interpreter Pythona odczytuje plik źródłowy, robi dwie rzeczy:
ustawia kilka specjalnych zmiennych
__name__
, a następniewykonuje cały kod znaleziony w pliku.
Zobaczmy, jak to działa i jak odnosi się do twojego pytania na temat
__name__
kontroli, które zawsze widzimy w skryptach Pythona.Próbka kodu
Użyjmy nieco innej próbki kodu, aby zbadać działanie importów i skryptów. Załóżmy, że w pliku o nazwie jest następujący
foo.py
.Specjalne zmienne
Kiedy interpreter Pythona odczytuje plik źródłowy, najpierw definiuje kilka specjalnych zmiennych. W tym przypadku zależy nam na
__name__
zmiennej.Gdy moduł jest programem głównym
Jeśli uruchamiasz moduł (plik źródłowy) jako program główny, np
interpreter przypisze ciąg zakodowany na stałe
"__main__"
do__name__
zmiennej, tjGdy Twój moduł jest importowany przez inną osobę
Z drugiej strony załóżmy, że jakiś inny moduł jest programem głównym i importuje go. Oznacza to, że taka instrukcja znajduje się w głównym programie lub w innym module, który importuje główny program:
Interpreter wyszuka Twój
foo.py
plik (wraz z kilkoma innymi wariantami), a przed uruchomieniem tego modułu przypisze nazwę"foo"
ze instrukcji importu do__name__
zmiennej, tj.Wykonanie kodu modułu
Po skonfigurowaniu zmiennych specjalnych interpreter wykonuje cały kod w module, po jednej instrukcji na raz. Możesz otworzyć inne okno z przykładowym kodem, aby postępować zgodnie z tym wyjaśnieniem.
Zawsze
Drukuje ciąg
"before import"
(bez cudzysłowów).Ładuje
math
moduł i przypisuje go do zmiennej o nazwiemath
. Jest to równoznaczne z zastąpieniemimport math
poniższym (zwróć uwagę, że__import__
jest to funkcja niskiego poziomu w Pythonie, która pobiera ciąg i wyzwala rzeczywisty import):Drukuje ciąg
"before functionA"
.Wykonuje
def
blok, tworząc obiekt funkcji, a następnie przypisując ten obiekt funkcji do zmiennej o nazwiefunctionA
.Drukuje ciąg
"before functionB"
.Wykonuje drugi
def
blok, tworząc inny obiekt funkcji, a następnie przypisując go do zmiennej o nazwiefunctionB
.Drukuje ciąg
"before __name__ guard"
.Tylko wtedy, gdy moduł jest programem głównym
__name__
rzeczywiście został ustawiony na"__main__"
i wywołuje dwie funkcje, wypisując ciągi"Function A"
i"Function B 10.0"
.Tylko wtedy, gdy moduł zostanie zaimportowany przez inną osobę
__name__
będzie"foo"
, nie"__main__"
, i będzie to pominąć ciałoif
oświadczeniu.Zawsze
"after __name__ guard"
w obu sytuacjach.Podsumowanie
Podsumowując, oto, co zostanie wydrukowane w dwóch przypadkach:
Dlaczego to działa w ten sposób?
Możesz oczywiście zastanawiać się, dlaczego ktoś tego chce. Czasami chcesz napisać
.py
plik, który może być używany przez inne programy i / lub moduły jako moduł, a także może być uruchomiony jako sam program główny. Przykłady:Twój moduł jest biblioteką, ale chcesz mieć tryb skryptu, w którym uruchamia on niektóre testy jednostkowe lub demonstrację.
Moduł jest używany tylko jako program główny, ale ma pewne testy jednostkowe, a środowisko testowe działa poprzez importowanie
.py
plików takich jak skrypt i uruchamianie specjalnych funkcji testowych. Nie chcesz, aby próbował uruchomić skrypt tylko dlatego, że importuje moduł.Twój moduł jest najczęściej używany jako program główny, ale zapewnia także interfejs API przyjazny dla programistów dla zaawansowanych użytkowników.
Poza tymi przykładami elegancko jest, że uruchomienie skryptu w Pythonie to tylko skonfigurowanie kilku magicznych zmiennych i zaimportowanie skryptu. „Uruchomienie” skryptu to efekt uboczny importowania modułu skryptu.
Jedzenie dla przemyślenia
Pytanie: Czy mogę mieć wiele
__name__
bloków sprawdzających? Odpowiedź: to dziwne, ale język cię nie powstrzyma.Załóżmy, że następujące elementy są w
foo2.py
. Co się stanie, jeśli powieszpython foo2.py
w wierszu poleceń? Dlaczego?__name__
odprawęfoo3.py
:źródło
subprocess.run('foo_bar.py')
skrypt w języku Python? Przypuszczam, żefoo_bar
zacznie się__name__ = '__main__'
tak, jak wtedy, gdyfoo_bar.py
ręcznie przesuwam cmd. Czy tak jest w przypadku? Biorąc pod uwagę odpowiedź @MrFooz, nie powinno być żadnego problemu z robieniem tego i posiadaniem tylu „głównych” modułów na raz, ile chcę. Nawet zmiana__name__
wartości lub posiadanie kilku niezależnych instancji (lub instancji, które się utworzyłysubprocess
) współdziałają ze sobą, powinno być jak zwykle dla Pythona. Czy coś mi umknęło?subprocess.run
. To powiedziawszy, ogólnie lepszym sposobem współdzielenia kodu między skryptami jest tworzenie modułów i skrypty wywoływały moduły współdzielone zamiast wywoływać się nawzajem jako skrypty. Trudno jest debugowaćsubprocess.run
wywołania, ponieważ większość debuggerów nie przeskakuje poza granice procesów, może dodać niebanalny narzut systemu, aby utworzyć i zniszczyć dodatkowe procesy itp.from foo2 import functionB
importować foo2 z funkcji B? To semantyczne zniekształcenie.from module import method
importuje metodę z modułu.multiprocessing
w szczególności konieczność przeprowadzenia tego testu w systemie Windows.Po uruchomieniu skryptu, przekazując go jako polecenie do interpretera języka Python,
wykonywany jest cały kod na poziomie wcięcia 0. Zdefiniowane funkcje i klasy są dobrze zdefiniowane, ale żaden z ich kodów nie jest uruchamiany. W przeciwieństwie do innych języków, żadna
main()
funkcja nie jest uruchamiana automatycznie -main()
domyślnie jest to cały kod na najwyższym poziomie.W tym przypadku kodem najwyższego poziomu jest
if
blok.__name__
jest wbudowaną zmienną, której wynikiem jest nazwa bieżącego modułu. Jeśli jednak moduł jest uruchamiany bezpośrednio (jakmyscript.py
powyżej),__name__
zamiast tego ustawiany jest ciąg"__main__"
. W ten sposób możesz przetestować, czy skrypt jest uruchamiany bezpośrednio, czy importowany przez coś innego, testującJeśli twój skrypt jest importowany do innego modułu, jego różne funkcje i definicje klas zostaną zaimportowane, a jego kod najwyższego poziomu zostanie wykonany, ale kod w
if
tekście powyższej klauzuli nie zostanie uruchomiony, ponieważ warunek jest następujący: nie spełnione Jako podstawowy przykład rozważ następujące dwa skrypty:Teraz, jeśli wywołasz interpretera jako
Wyjście będzie
Jeśli
two.py
zamiast tego uruchomisz :Dostajesz
Zatem, gdy moduł
one
zostanie załadowany, jego wartość__name__
jest równa"one"
zamiast"__main__"
.źródło
Najprostsze wyjaśnienie
__name__
zmiennej (imho) jest następujące:Utwórz następujące pliki.
i
Uruchomienie ich zapewni ci następujące dane wyjściowe:
Jak widać, po zaimportowaniu modułu Python ustawia
globals()['__name__']
w tym module nazwę modułu. Ponadto po zaimportowaniu cały kod w module jest uruchamiany. Jakif
oświadczenie ocenia,False
ta część nie jest wykonywana.Jak widać, po uruchomieniu pliku Python ustawia
globals()['__name__']
w tym pliku wartość"__main__"
. Tym razemif
instrukcja oceniaTrue
i jest uruchamiana.źródło
Aby przedstawić podstawy:
Zmienna globalna
__name__
w module będącym punktem wejścia do programu to'__main__'
. W przeciwnym razie jest to nazwa, którą importujesz moduł.Tak więc kod pod
if
blokiem będzie działał tylko wtedy, gdy moduł będzie punktem wejścia do twojego programu.Umożliwia importowanie kodu z modułu przez inne moduły bez wykonywania bloku kodu poniżej podczas importu.
Dlaczego tego potrzebujemy?
Opracowywanie i testowanie kodu
Załóżmy, że piszesz skrypt w języku Python zaprojektowany jako moduł:
Państwo mogli przetestować moduł dodając ten wywołanie funkcji do dołu:
i uruchomienie go (w wierszu polecenia) za pomocą czegoś takiego:
Problem
Jeśli jednak chcesz zaimportować moduł do innego skryptu:
Podczas importu
do_important
funkcja zostanie wywołana, więc prawdopodobnie skomentujesz swoje wywołanie funkcjido_important()
na dole.A potem będziesz musiał pamiętać, czy skomentowałeś swoje wywołanie funkcji testowej. Ta dodatkowa złożoność oznaczałaby, że prawdopodobnie zapomnisz, co utrudni proces rozwoju.
Lepszy sposób
Te
__name__
punkty zmienną do nazw gdziekolwiek interpreter Pythona dzieje się w tej chwili.W zaimportowanym module jest to nazwa tego modułu.
Ale wewnątrz modułu podstawowego (lub interaktywnej sesji Pythona, tj. Read, Eval, Print Loop lub REPL) interpretujesz wszystko z jego poziomu
"__main__"
.Więc jeśli sprawdzisz przed wykonaniem:
W związku z powyższym kod będzie wykonywany tylko wtedy, gdy zostanie uruchomiony jako moduł podstawowy (lub celowo wywoływany z innego skryptu).
Jeszcze lepszy sposób
Istnieje jednak Pythoniczny sposób, aby to poprawić.
Co jeśli chcemy uruchomić ten proces biznesowy spoza modułu?
Jeśli umieścimy kod, który chcemy ćwiczyć podczas opracowywania i testowania w funkcji takiej jak ta, a następnie sprawdzamy, czy
'__main__'
natychmiast:Mamy teraz ostatnią funkcję na końcu naszego modułu, która będzie działać, jeśli uruchomimy moduł jako moduł podstawowy.
Umożliwi to zaimportowanie modułu oraz jego funkcji i klas do innych skryptów bez uruchamiania
main
funkcji, a także pozwoli na wywołanie modułu (i jego funkcji i klas) podczas uruchamiania z innego'__main__'
modułu, tj.Ten idiom można również znaleźć w dokumentacji Pythona w objaśnieniu
__main__
modułu. Ten tekst stanowi:źródło
if __name__ == "__main__"
to część, która działa, gdy skrypt jest uruchamiany z (powiedzmy) wiersza poleceń za pomocą polecenia podobnegopython myscript.py
.źródło
helloworld.py
z tym plikiemprint("hello world")
może działać z poleceniem,python helloworld.py
nawet jeśli go nie maif __name__ == "__main__"
?__name__
jest zmienną globalną (w Pythonie globalnie oznacza na poziomie modułu ), która istnieje we wszystkich przestrzeniach nazw. Zazwyczaj jest to nazwa modułu (jakostr
typ).Jednak jako jedyny szczególny przypadek w każdym uruchomionym procesie Pythona, jak w mycode.py:
skądinąd anonimowy nazw globalny jest przypisana wartość
'__main__'
do ITS__name__
.Zatem łącznie z ostatnimi liniami
spowoduje
main
uruchomienie unikatowej funkcji skryptu .Kolejna zaleta korzystania z tej konstrukcji: możesz również zaimportować kod jako moduł w innym skrypcie, a następnie uruchomić główną funkcję, jeśli i kiedy program zdecyduje:
źródło
Istnieje wiele różnych podejść do mechaniki omawianego kodu, „How”, ale dla mnie żadne z nich nie miało sensu, dopóki nie zrozumiałem „Dlaczego”. Powinno to być szczególnie pomocne dla nowych programistów.
Weź plik „ab.py”:
I drugi plik „xy.py”:
Kiedy wykonujesz
xy.py
, tyimport ab
. Instrukcja import uruchamia moduł natychmiast po imporcie, więcab
operacje są wykonywane przed pozostałą częściąxy
. Po zakończeniuab
kontynuuje sięxy
.Tłumacz interpretuje, które skrypty są uruchomione
__name__
. Po uruchomieniu skryptu - bez względu na to, jak go nazwiesz - interpreter wywołuje go"__main__"
, co czyni go skryptem głównym lub „domowym”, do którego wraca po uruchomieniu skryptu zewnętrznego.Każdy inny skrypt, który jest wywoływany z tego
"__main__"
skryptu, ma przypisaną nazwę pliku jako__name__
(np__name__ == "ab.py"
.). Dlatego liniaif __name__ == "__main__":
jest testem interpretera w celu ustalenia, czy interpretuje / analizuje skrypt „domowy”, który został początkowo wykonany, czy też tymczasowo zagląda do innego (zewnętrznego) skryptu. Daje to programiście elastyczność, aby skrypt działał inaczej, jeśli jest wykonywany bezpośrednio, a nie wywoływany zewnętrznie.Przejdźmy przez powyższy kod, aby zrozumieć, co się dzieje, skupiając się najpierw na niezróżnicowanych liniach i kolejności, w jakiej pojawiają się w skryptach. Pamiętaj, że funkcja - lub
def
- bloki nie robią nic same, dopóki nie zostaną wywołane. Co powiedziałby tłumacz, gdyby wymamrotał do siebie:"__main__"
w__name__
zmiennej.__name__ == "ab.py"
.a()
; Właśnie się tego nauczyłem. Drukowanie „ Funkcja w pliku ab ”."__main__"
!x()
; ok, drukowanie „ zadania peryferyjnego: może być przydatne w innych projektach ”.if
Stwierdzenie. Cóż, warunek został spełniony (zmienna__name__
została ustawiona na"__main__"
), więc wejdę domain()
funkcji i wypiszę „ główną funkcję: tutaj jest akcja ”.Dwie dolne linie oznaczają: „Jeśli jest to
"__main__"
skrypt„ domowy ”, wykonaj funkcję o nazwiemain()
„. Dlatego zobaczyszdef main():
blok do góry, który zawiera główny przepływ funkcji skryptu.Pamiętasz, co powiedziałem wcześniej o wyciągach z importu? Podczas importowania modułu nie tylko go „rozpoznaje” i czeka na dalsze instrukcje - w rzeczywistości uruchamia wszystkie operacje wykonywalne zawarte w skrypcie. Tak więc umieszczenie mięsa skryptu w
main()
funkcji skutecznie poddaje go kwarantannie, umieszczając go w izolacji, aby nie uruchomił się natychmiast po zaimportowaniu przez inny skrypt.Znowu będą wyjątki, ale powszechną praktyką jest to, że
main()
zwykle nie wywołuje się ich na zewnątrz. Być może zastanawiasz się jeszcze jedną rzecz: jeśli nie dzwonimymain()
, dlaczego w ogóle wywołujemy skrypt? Jest tak, ponieważ wiele osób tworzy swoje skrypty przy użyciu samodzielnych funkcji, które są zbudowane tak, aby działały niezależnie od reszty kodu w pliku. Następnie są wywoływani gdzieś indziej w treści skryptu. Co prowadzi mnie do tego:Tak to prawda. Te osobne funkcje można wywoływać z wbudowanego skryptu, który nie jest zawarty w
main()
funkcji. Jeśli jesteś przyzwyczajony (tak jak ja, na wczesnych etapach programowania) do tworzenia skryptów online, które robią dokładnie to, czego potrzebujesz, i spróbujesz to rozgryźć, jeśli kiedykolwiek będziesz potrzebować tej operacji. ... cóż, nie jesteś przyzwyczajony do tego rodzaju wewnętrznej struktury kodu, ponieważ jest on bardziej skomplikowany w budowie i nie jest tak intuicyjny w czytaniu.Jest to jednak skrypt, który prawdopodobnie nie może wywoływać swoich funkcji zewnętrznie, ponieważ gdyby to zrobił, natychmiast zacząłby obliczać i przypisywać zmienne. Są szanse, że jeśli spróbujesz ponownie użyć funkcji, twój nowy skrypt jest wystarczająco blisko powiązany ze starym, że wystąpią sprzeczne zmienne.
Dzieląc niezależne funkcje, zyskujesz możliwość ponownego wykorzystania poprzedniej pracy przez wywołanie ich w innym skrypcie. Na przykład „example.py” może importować „xy.py” i wywoływać
x()
, wykorzystując funkcję „x” z „xy.py”. (Być może jest to pisanie wielkimi literami trzeciego słowa danego ciągu tekstowego; tworzenie tablicy NumPy z listy liczb i ich kwadratowanie; lub zniechęcanie powierzchni 3D. Możliwości są nieograniczone.)( Nawiasem mówiąc , to pytanie zawiera odpowiedź @kindall, która w końcu pomogła mi zrozumieć - dlaczego, a nie jak. Niestety oznaczono go jako duplikat tego , co uważam za błąd).
źródło
Kiedy w naszym module (
M.py
) są pewne instrukcje, które chcemy wykonać, gdy będą działać jako główne (nie importowane), możemy umieścić te instrukcje (przypadki testowe, instrukcje drukowania) w tymif
bloku.Domyślnie (gdy moduł działa jako główny, nie importowany)
__name__
zmienna jest ustawiona na"__main__"
, a kiedy zostanie zaimportowana,__name__
zmienna otrzyma inną wartość, najprawdopodobniej nazwę modułu ('M'
). Jest to pomocne w jednoczesnym uruchamianiu różnych wariantów modułów i oddzielaniu ich specyficznych instrukcji wejścia i wyjścia, a także w przypadku wystąpienia przypadków testowych.Krótko mówiąc , użyj tego
if __name__ == "main"
bloku, aby zapobiec uruchomieniu (pewnego) kodu podczas importowania modułu.źródło
Mówiąc prościej,
__name__
jest zmienną zdefiniowaną dla każdego skryptu, która określa, czy skrypt jest uruchamiany jako moduł główny, czy jest uruchamiany jako moduł importowany.Więc jeśli mamy dwa skrypty;
i
Dane wyjściowe z wykonania skryptu 1 to
A wynikiem działania script2 jest:
Jak widać,
__name__
mówi nam, który kod jest modułem „głównym”. Jest to świetne, ponieważ możesz po prostu pisać kod i nie martwić się o problemy strukturalne, takie jak w C / C ++, gdzie jeśli plik nie implementuje funkcji „głównej”, to nie można go skompilować jako pliku wykonywalnego, a jeśli tak, nie można go wtedy wykorzystać jako biblioteki.Załóżmy, że piszesz skrypt w języku Python, który robi coś wspaniałego i implementujesz mnóstwo funkcji przydatnych w innych celach. Jeśli chcę ich użyć, mogę po prostu zaimportować skrypt i użyć go bez uruchamiania programu (biorąc pod uwagę, że kod działa tylko w
if __name__ == "__main__":
kontekście). Podczas gdy w C / C ++ trzeba by podzielić te elementy na osobny moduł, który następnie zawiera plik. Wyobraź sobie sytuację poniżej;Strzałki to linki do importu. Dla trzech modułów, z których każdy próbuje dołączyć kod poprzedniego modułu, jest sześć plików (dziewięć, licząc pliki implementacyjne) i pięć linków. Utrudnia to włączenie innego kodu do projektu C, chyba że jest on skompilowany specjalnie jako biblioteka. Teraz wyobraź to dla Pythona:
Piszesz moduł, a jeśli ktoś chce użyć twojego kodu, po prostu go importuje, a
__name__
zmienna może pomóc oddzielić wykonalną część programu od części biblioteki.źródło
Spójrzmy na odpowiedź w bardziej abstrakcyjny sposób:
Załóżmy, że mamy ten kod w
x.py
:Bloki A i B są uruchamiane, gdy działamy
x.py
.Ale blok A (a nie B) jest uruchamiany, gdy uruchamiamy inny moduł,
y.py
na przykład, w którymx.py
jest importowany, a kod jest uruchamiany stamtąd (na przykład, gdyx.py
wywoływana jest funkcja iny.py
).źródło
Podczas interaktywnego uruchamiania Pythona
__name__
zmiennej lokalnej przypisywana jest wartość__main__
. Podobnie, gdy uruchamiasz moduł Python z wiersza poleceń, zamiast importować go do innego modułu, jego__name__
atrybutowi przypisywana jest wartość__main__
, a nie rzeczywista nazwa modułu. W ten sposób moduły mogą przyjrzeć się własnej__name__
wartości, aby samodzielnie ustalić, w jaki sposób są używane, czy to jako wsparcie dla innego programu, czy jako główna aplikacja wykonywana z wiersza poleceń. Dlatego następujący idiom jest dość powszechny w modułach Python:źródło
Rozważać:
Sprawdza, czy
__name__
atrybut skryptu Python jest"__main__"
. Innymi słowy, jeśli sam program zostanie wykonany, atrybut będzie__main__
, więc program zostanie wykonany (w tym przypadkumain()
funkcja).Jeśli jednak moduł Pythona jest używany przez moduł,
if
zostanie wykonany dowolny kod poza instrukcją, więcif \__name__ == "\__main__"
służy on tylko do sprawdzenia, czy program jest używany jako moduł, czy nie, i dlatego decyduje, czy uruchomić kod.źródło
Przed wyjaśnieniem czegokolwiek na temat
if __name__ == '__main__'
ważne jest, aby zrozumieć, co__name__
jest i co robi.__name__
jest DunderAlias - można go traktować jako zmienną globalną (dostępną z modułów) i działa w podobny sposóbglobal
.Jest to ciąg (globalny, jak wspomniano powyżej), jak wskazano przez
type(__name__)
(ustępowanie<class 'str'>
), i jest wbudowanym standardem zarówno dla wersji Python 3, jak i Python 2 .Można go używać nie tylko w skryptach, ale można go również znaleźć zarówno w interpreterie, jak i modułach / pakietach.
Interpretator:
Scenariusz:
test_file.py :
Wynikające z
__main__
Moduł lub pakiet:
somefile.py:
test_file.py:
Wynikające z
somefile
Zauważ, że gdy jest używany w pakiecie lub module,
__name__
przyjmuje nazwę pliku. Ścieżka rzeczywistej ścieżki modułu lub pakietu nie jest podana, ale ma własną DunderAlias__file__
, która pozwala na to.Powinieneś zobaczyć, że gdzie
__name__
, gdzie jest to główny plik (lub program), zawsze będzie zwracany__main__
, a jeśli jest to moduł / pakiet lub cokolwiek, co działa z innym skryptem Pythona, zwróci nazwę pliku, w którym jest pochodzi z.Bycie zmienną oznacza, że jej wartość może zostać nadpisana („może” nie oznacza „powinna”), nadpisanie wartości
__name__
spowoduje brak czytelności. Więc nie rób tego z jakiegokolwiek powodu. Jeśli potrzebujesz zmiennej, zdefiniuj nową zmienną.Zawsze przyjmuje się, że wartość
__name__
to__main__
lub nazwa pliku. Ponowna zmiana tej wartości domyślnej spowoduje więcej zamieszania, że zrobi to dobrze, powodując problemy w dalszej linii.przykład:
Ogólnie uważa się za dobrą praktykę włączanie
if __name__ == '__main__'
skryptów.Teraz wiemy, że zachowanie się
__name__
rzeczy staje się wyraźniejsze:Jest
if
to instrukcja kontroli przepływu, która zawiera blok kodu, zostanie wykonana, jeśli podana wartość jest prawdą. Widzieliśmy, że__name__
może to zająć albo__main__
nazwę pliku, z którego został zaimportowany.Oznacza to, że jeśli
__name__
jest równe,__main__
to plik musi być plikiem głównym i musi faktycznie działać (lub jest to interpreter), a nie moduł lub pakiet zaimportowany do skryptu.Jeśli rzeczywiście
__name__
przyjmie wartość,__main__
to wszystko, co jest w tym bloku kodu, zostanie wykonane.To mówi nam, że jeśli uruchomiony plik jest plikiem głównym (lub bezpośrednio z interpretera), to warunek ten musi zostać spełniony. Jeśli jest to pakiet, nie powinien, a wartość nie będzie
__main__
.__name__
może być również użyty w modułach do zdefiniowania nazwy modułuMożna także robić inne, mniej powszechne, ale przydatne rzeczy
__name__
, niektóre pokażę tutaj:Wykonywanie tylko, jeśli plik jest modułem lub pakietem:
Uruchamianie jednego warunku, jeśli plik jest głównym, a drugiego, jeśli nie jest:
Można go również użyć do zapewnienia uruchomionych funkcji pomocy / programów narzędziowych na pakietach i modułach bez skomplikowanego korzystania z bibliotek.
Umożliwia także uruchamianie modułów z wiersza poleceń jako głównych skryptów, co może być również bardzo przydatne.
źródło
Myślę, że najlepiej jest udzielić odpowiedzi dogłębnie i prostymi słowami:
__name__
: Każdy moduł w Pythonie ma specjalny atrybut o nazwie__name__
. Jest to wbudowana zmienna, która zwraca nazwę modułu.__main__
: Podobnie jak inne języki programowania, również Python ma punkt wejścia wykonania, tj. Main.'__main__'
to nazwa zakresu, w którym wykonywany jest kod najwyższego poziomu . Zasadniczo masz dwa sposoby korzystania z modułu Python: Uruchom go bezpośrednio jako skrypt lub zaimportuj. Gdy moduł jest uruchamiany jako skrypt,__name__
jest ustawiony na__main__
.W ten sposób wartość
__name__
atrybutu jest ustawiana,__main__
gdy moduł jest uruchamiany jako program główny. W przeciwnym razie wartość__name__
jest ustawiona tak, aby zawierała nazwę modułu.źródło
Jest to specjalne, gdy plik Python jest wywoływany z wiersza poleceń. Jest to zwykle używane do wywoływania funkcji „main ()” lub wykonania innego odpowiedniego kodu startowego, na przykład obsługi argumentów wiersza poleceń.
Można to napisać na kilka sposobów. Innym jest:
Nie twierdzę, że powinieneś używać tego w kodzie produkcyjnym, ale służy to zilustrowaniu, że nie ma w tym nic „magicznego”
if __name__ == '__main__'
. Jest to dobra konwencja do wywoływania głównej funkcji w plikach Python.źródło
and
.and
służy do sprawdzania, czy obie instrukcje boolowskie są prawdziwe. Ponieważ nie jesteś zainteresowany wynikiemand
,if
oświadczenie wyraźniej komunikuje twoje intencje.Istnieje wiele zmiennych, które system (interpreter języka Python) udostępnia dla plików źródłowych (modułów). Możesz uzyskać ich wartości w dowolnym momencie, więc skupmy się na zmiennej / atrybucie __name__ :
Gdy Python ładuje plik kodu źródłowego, wykonuje cały znajdujący się w nim kod. (Pamiętaj, że nie wywołuje wszystkich metod i funkcji zdefiniowanych w pliku, ale je definiuje.)
Jednak zanim interpreter wykona plik kodu źródłowego, definiuje kilka specjalnych zmiennych dla tego pliku; __imię__ jest jedną ze specjalnych zmiennych, które Python automatycznie definiuje dla każdego pliku kodu źródłowego.
Jeśli Python ładuje ten plik kodu źródłowego jako główny program (tj. Plik, który uruchamiasz), wówczas ustawia specjalną zmienną __name__ dla tego pliku na wartość „__main__” .
Jeśli jest importowany z innego modułu, __name__ zostanie ustawiony na nazwę tego modułu.
Tak więc w twoim przykładzie częściowo:
oznacza, że blok kodu:
zostanie wykonany tylko wtedy, gdy moduł zostanie uruchomiony bezpośrednio; blok kodu nie zostanie wykonany, jeśli inny moduł go wywołuje / importuje, ponieważ wartość __name__ nie będzie równa „ main ” w tym konkretnym przypadku.
Mam nadzieję, że to pomaga.
źródło
if __name__ == "__main__":
jest zasadniczo środowiskiem skryptowym najwyższego poziomu i określa interpreter, który („Mam najwyższy priorytet do wykonania jako pierwszy”).'__main__'
to nazwa zakresu, w którym wykonywany jest kod najwyższego poziomu. Moduł__name__
jest ustawiony na równy,'__main__'
gdy jest czytany ze standardowego wejścia, skryptu lub z interaktywnego monitu.źródło
Tak wiele czytałem w odpowiedziach na tej stronie. Powiedziałbym, że jeśli znasz tę rzecz, na pewno zrozumiesz te odpowiedzi, w przeciwnym razie nadal będziesz zdezorientowany.
Krótko mówiąc, musisz znać kilka punktów:
import a
akcja faktycznie uruchamia wszystko, co można uruchomić w „a”Z powodu punktu 1 możesz nie chcieć, aby wszystko było uruchamiane w „a” podczas importowania
Aby rozwiązać problem w punkcie 2, python pozwala na sprawdzenie warunku
__name__
jest zmienną domyślną we wszystkich.py
modułach; gdya.py
jest importowany, wartość__name__
za.py
modułu jest ustawiony na swoją nazwę pliku "a
„; gdya.py
jest prowadzony bezpośrednio za pomocą „python a.py
”, co oznacza, żea.py
jest punktem wyjścia, wtedy wartość__name__
za.py
modułu jest ustawione na sznurku__main__
__name__
Czy wiesz, jak osiągnąć punkt 3 w oparciu o mechanizm, w jaki sposób Python ustawia zmienną dla każdego modułu? Odpowiedź jest dość łatwa, prawda? Umieść jeśli warunek:if __name__ == "__main__": ...
; możesz nawet umieścić, jeśli__name__ == "a"
zależy to od twoich potrzeb funkcjonalnychWażną rzeczą, w której Python jest wyjątkowy, jest punkt 4! Reszta to tylko podstawowa logika.
źródło
Rozważać:
Wynik dla powyższego jest
__main__
.Powyższe stwierdzenie jest prawdziwe i wypisuje „metodę bezpośrednią” . Załóżmy, że jeśli zaimportowali tę klasę do innej klasy, nie wydrukuje ona „metody bezpośredniej”, ponieważ podczas importowania zostanie ustawiona
__name__ equal to "first model name"
.źródło
fibo.py (moduł o nazwie
fibo
)Odniesienie: https://docs.python.org/3.5/tutorial/modules.html
źródło
Powód dla
polega przede wszystkim na uniknięciu problemów z blokadą importu , które powstałyby w wyniku bezpośredniego importowania kodu . Chcesz
main()
uruchomić, jeśli plik został bezpośrednio wywołany (to jest__name__ == "__main__"
przypadku), ale jeśli kod został zaimportowany, wówczas importer musi wprowadzić kod z prawdziwego modułu głównego, aby uniknąć problemów z blokadą importu.Efektem ubocznym jest automatyczne zalogowanie się do metodologii obsługującej wiele punktów wejścia. Możesz uruchomić swój program, używając
main()
jako punktu wejścia, ale nie musisz . Podczas gdysetup.py
oczekujemain()
, inne narzędzia używają alternatywnych punktów wejścia. Na przykład, aby uruchomić plik jakogunicorn
proces, należy zdefiniowaćapp()
funkcję zamiastmain()
. Podobnie jak w przypadkusetup.py
,gunicorn
importuj kod, abyś nie chciał nic robić podczas importowania (z powodu problemu z blokadą importu).źródło
Ta odpowiedź jest dla programistów Java uczących się języka Python. Każdy plik Java zazwyczaj zawiera jedną klasę publiczną. Możesz użyć tej klasy na dwa sposoby:
Zadzwoń do klasy z innych plików. Musisz tylko zaimportować go do programu wywołującego.
Uruchom klasę samodzielnie, do celów testowych.
W drugim przypadku klasa powinna zawierać publiczną statyczną metodę void main (). W Pythonie ten cel jest obsługiwany przez globalnie zdefiniowaną etykietę
'__main__'
.źródło
Kod poniżej
if __name__ == '__main__':
zostanie wykonany tylko wtedy, gdy moduł zostanie wywołany jako skrypt .Jako przykład rozważ następujący moduł
my_test_module.py
:Pierwsza możliwość: import
my_test_module.py
do innego modułuTeraz, jeśli wywołasz
main.py
:Należy pamiętać, że tylko najwyższego poziomu
print()
oświadczenie wmy_test_module
jest wykonywany.Druga możliwość: wywołaj
my_test_module.py
jako skryptTeraz, jeśli działasz
my_test_module.py
jako skrypt Pythona, obieprint()
instrukcje zostaną wykonane:źródło
Każdy moduł w pythonie ma atrybut o nazwie
__name__
. Wartość__name__
atrybutu polega__main__
na bezpośrednim uruchomieniu modułu, nppython my_module.py
. W przeciwnym razie (tak jak mówiszimport my_module
) wartość__name__
jest nazwa modułu.Mały przykład do wyjaśnienia w skrócie.
Możemy to wykonać bezpośrednio jako
Wynik
Załóżmy teraz, że wywołujemy powyższy skrypt z innego skryptu
Kiedy to wykonasz
Wynik
Tak, powyżej jest wymowne, że po wywołaniu testu z innego skryptu, jeśli pętla
__name__
wtest.py
nie wykona.źródło
Jeśli ten plik .py zostanie zaimportowany przez inne pliki .py, kod pod „instrukcją if” nie zostanie wykonany.
Jeśli ten plik .py jest uruchamiany
python this_py.py
pod powłoką lub dwukrotnie kliknięty w systemie Windows. kod pod „instrukcją if” zostanie wykonany.Zwykle jest napisane do testowania.
źródło
Jeśli interpreter Pythona uruchamia określony moduł, wówczas
__name__
zmienna globalna będzie miała wartość"__main__"
Kiedy uruchomisz ten skrypt , możesz mnie zobaczyć
za
Jeśli zaimportujesz ten plik, powiedz A do pliku B i uruchom plik B, a następnie
if __name__ == "__main__"
plik A stanie się fałszem, więc zostanie wydrukowany. Nie widzisz mnieb
źródło
Wszystkie odpowiedzi wyjaśniły funkcjonalność. Podam jednak jeden przykład jego użycia, który może pomóc w dalszym dopracowaniu koncepcji.
Załóżmy, że masz dwa pliki Python, a.py i b.py. Teraz a.py importuje b.py. Uruchamiamy plik a.py, w którym kod „import b.py” jest wykonywany jako pierwszy. Przed uruchomieniem reszty kodu a.py kod w pliku b.py musi zostać uruchomiony w całości.
W kodzie b.py jest jakiś kod, który jest wyłączny dla tego pliku b.py i nie chcemy, aby inny plik (inny niż plik b.py), który zaimportował plik b.py, go uruchomił.
Tak właśnie sprawdza ten wiersz kodu. Jeśli jest to główny plik (tj. B.py) z uruchomionym kodem, co w tym przypadku nie jest (a.py jest uruchomionym plikiem głównym), wówczas wykonywany jest tylko kod.
źródło
Utwórz plik a.py :
__name__
jest zawsze równy__main__
każdorazowemu uruchomieniu tego pliku, co pokazuje, że jest to plik główny.Utwórz kolejny plik b.py w tym samym katalogu:
Uruchom. Będzie ona drukować , czyli nazwę pliku, który jest importowany .
Tak więc, aby pokazać dwa różne zachowania tego samego pliku , jest to często stosowana sztuczka:
źródło
if name == ' main ':
Widzimy czy
__name__ == '__main__':
dość często.Sprawdza, czy moduł jest importowany, czy nie.
Innymi słowy, kod w
if
bloku zostanie wykonany tylko wtedy, gdy kod zostanie uruchomiony bezpośrednio. Tutajdirectly
oznaczanot imported
.Zobaczmy, co robi, używając prostego kodu, który wypisuje nazwę modułu:
Jeśli uruchomimy kod bezpośrednio przez
python test.py
, nazwa modułu to__main__
:źródło
Po prostu jest to punkt wejściowy do uruchomienia pliku, podobnie jak
main
funkcja w języku programowania C.źródło
if __name__ == "__main__"
blokiem nie ma kodu (oprócz definicji bez skutków ubocznych) . Technicznie szczytem wykonanego skryptu jest punkt wejścia programu.