2012-11-10 14 views
12

Powiel możliwe:
What does <if __name__==“__main__”:> do?Nie rozumiem głównego bloku Pythona. Co to jest?

Więc zacznę się pyscripter i dostaję plik z tym w tym:

def main(): 
    pass 

if __name__ == '__main__': 
    main() 

Co to jest? Dlaczego mój program działa również bez niego? Jaki jest cel tego? Gdzie będzie mój kod? Powiedzmy, funkcja, która drukuje Witaj świecie. Gdzie to się podział? gdzie mam to nazwać?

+0

dlaczego to się zaczyna podbijać ze wszystkimi tymi duplikatami? – none

+1

Ponieważ to pytanie dotyczy bardzo szerokiej gamy książek pod-pytań, nie wyszczególniaj ani nie zadawaj innych pytań, które wskazałeś powyżej. – user836087

Odpowiedz

12

Zasadniczo celem jest zdefiniowanie centralnego punktu wejścia, wtedy i tylko wtedy, gdy skrypt jest uruchamiany bezpośrednio. Ponieważ __name__ będzie zawsze równy '__main__', jeśli jest uruchamiany samodzielnie. Umieszczenie rzeczywistej zawartości skryptu w oddzielnej funkcji umożliwia innym skryptom zaimportowanie tej funkcji i uruchomienie jej w dowolnym momencie, tak aby nie była uruchamiana natychmiast po zaimportowaniu skryptu.

Jest to często używane w modułach biblioteki do domyślnego zachowania, gdy potrzebujesz czegoś szybko. Na przykład moduł http.server oferuje szeroką funkcjonalność do tworzenia własnego serwera HTTP z dowolnymi funkcjami, jakie można wymyślić. Jeśli chcesz szybko posortować statycznie i przesłać pliki statycznie, możesz po prostu użyć domyślnego zachowania modułu po uruchomieniu z wiersza poleceń.

Uruchamianie python3 -m http.server w wierszu polecenia będzie dokładnie to robić; uruchom moduł http.server, który sam rozpocznie prosty serwer HTTP w swoim bloku __name__ == '__main__.

W odpowiedzi na Twój komentarz:

dla zwykłych modułów, które działają jako biblioteki zawierają typy lub funkcje swoich potrzeb aplikacji, nie trzeba funkcję main lub główny blok. W przypadku skryptów, które są wywoływane bezpośrednio, na przykład skrypt startowy, który faktycznie uruchamia twoją aplikację, będziesz miał jakiś kod, który nie jest enkapsulowany w funkcjach lub klasach, ale działa bezpośrednio. To byłoby coś, można by umieścić główną funkcję, którą następnie wywołujecie osobno. Daje to nieco więcej swobody w zakresie umieszczania tego kodu. Na przykład możesz mieć funkcję main bezpośrednio na początku pliku, podczas gdy dodatkowe funkcje, które są wywoływane w niej, są zdefiniowane dalej w pliku. A ostatnia część skryptu to main(). Niekoniecznie musisz umieścić to w warunku if __main__ == '__main__':, możesz po prostu zadzwonić bezpośrednio. Tak na przykład skrypt może wyglądać następująco:

def main(): 
    # doing something 
    utilityFunction(...) 
    otherUtilityFunction(...) 

def utilityFunction (...): 
    ... 
def otherUtilityFunction (...): 
    ... 

main() 

Jeśli nie umieścić kod w osobnej funkcji, trzeba zrobić wszystko, przetwarzanie na dole (po twoich definicji funkcji) oraz że może być nieproduktywny, jeśli chcesz szybko zobaczyć, co robisz, gdy skrypt jest bezpośrednio wywoływany.

Teraz, jak już powiedziałem, nie trzeba umieszczać tego w głównym bloku; możesz po prostu zadzwonić bezpośrednio. Jeśli jednak z jakiegoś powodu konieczne jest dołączenie tego pliku, na przykład dlatego, że chcesz go enkapsulować na jakąś inną rzecz, lub jeśli chcesz wywoływać go wielokrotnie z interaktywnej powłoki (IDLE lub coś podobnego), prawdopodobnie nie chcesz uruchomić main() za każdym razem, gdy tylko importujesz moduł, ale tylko wtedy, gdy chcesz faktycznie wykonać jego funkcję.To tam powinieneś umieścić main() w stanie; w ten sposób nie zostanie wykonany, chyba że bezpośrednio wykonujesz moduł.

Ogólnie rzecz biorąc, nie jest złym pomysłem, aby zawsze umieszczać wywołanie main() w takim stanie, ponieważ nigdy nie będzie bolało, ale często stanie się przydatne w pewnym późniejszym momencie.

+2

Stwierdzasz, że '' __name__'' będzie zawsze równe '' __main__'' jeśli jest uruchom z wiersza poleceń. Chociaż istota jest prawdziwa, nie jest to ściśle faktyczne, możliwe jest uruchomienie tego kodu z poziomu skryptu python, który powiedział, że jest to coś, co trzeba wyraźnie spróbować zrobić. (E.g: z '' imp.load_module() ''). –

+0

@ Battsware Dobry punkt, poprawiono moją odpowiedź. – poke

+0

Poke. Nie rozumiem tego. Kiedy powinienem mieć główny blok w moim kodzie i kiedy nie powinienem? Powiedzmy, że mam 20 zależności plików Pythona, duży program. Gdzie jest główne znaczenie? – user836087

0

W rzeczywistości nie potrzebujesz tej sztuczki dla "Hello world", ale jest to przydatne na wypadek, gdy piszesz moduł. Klauzula if __name__ == '__main__' spowodowałaby, że uruchomiłaby ona main() tylko wtedy, gdy skrypt jest wykonywany bezpośrednio, a nie, jeśli jest używany jako import z innego skryptu.

3

Globalny __name__ jest ustawiony na __main__ podczas wykonywania pliku Pythona, podczas importowania pliku jest ustawiony na jego nazwę.

Ta konstrukcja pozwala na wykonanie kodu tylko wtedy, gdy plik zostanie wykonany. Na przykład, jeśli masz plik mymain.py:

def main(): 
    print('Hello, World!') 


if __name__ == '__main__': 
    main() 

ten otrzymasz wyniki:

$ python mymain.py 
Hello, World! 
$ python 
Python 2.7.3 (default, Aug 1 2012, 05:14:39) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mymain # main() *not* executed 
>>> mymain.main() 
Hello, World! 

to często przydatna jest w stanie zaimportować plik bez konieczności kod wykonywany. W ten sposób główna funkcja może zostać wywołana przez oprogramowanie stron trzecich bez konieczności tworzenia nowego procesu i umożliwienia im zmiany niektórych elementów przed uruchomieniem.

Nie jest to konieczne, ale dobrą praktyką jest korzystanie z niego. Często zdajesz sobie sprawę, że niektóre funkcje/klasy programu mogą być przydatne dla innego programu, więc dobra praktyka to możliwość importowania pliku bez wykonywania głównego programu.

Porównując do Javy mające blok if __name__ == '__main__': jest jak klasy, która ma tylko metody main i używa innych klas, aby wykonywać swoją pracę, a nie za pomocą to jest jak main metoda wewnątrz klasy, która udostępnia również inne funkcje (np. jakiś kontener lub cokolwiek z metodą main, która wykonuje główny program).

2

Wszystko w języku Python jest stwierdzeniem, nie ma czegoś takiego jak deklaracja (na przykład: def to instrukcja tworząca obiekt funkcji i wiążąca go z nazwą). Importowanie modułu oznacza (po pewnym księgowym) wykonanie instrukcji w module. Podobnie, wykonanie pliku Pythona oznacza zaimportowanie go jako modułu. W związku z tym wystarczy napisać program jako instrukcje na poziomie modułu.

Ale to oczywiście nie nadaje się do ponownego użycia. Kiedy "program" powinien być również możliwy do importowania dla innych modułów, umieszczasz go w funkcji (i jest kilka innych, mniejszych zalet). Ale wtedy wykonanie pliku (python file.py) nie wpłynęłoby na nic poza zdefiniowaniem tej funkcji.

Wprowadź __name__, która jest nazwą modułu i jest równa '__main__' dla modułu "punkt wejścia". Tak więc warunek sprawdza, czy moduł został zaimportowany lub uruchomiony jako skrypt, i wykonuje swoją pracę w tym drugim przypadku.

0

Pomysł jest dość prosty: możesz użyć tego pliku zarówno jako pakietu (coś do zaimportowania gdzieś), jak i jako czysty skrypt. Jeśli plik jest używany jako skrypt, zmienna interpretera Pythona "__name__" zawiera "__main__" zamiast nazwy pakietu.

Sprawdzamy, czy __name__ jest ustawiony na __main__, co oznacza, że ​​jesteśmy w trybie skryptowym, a jeśli tak, wykonujemy kod w bloku "if".

Musisz zrozumieć istotną różnicę między Javą i Pythonem: w Pythonie, kiedy interpreter odczytuje plik, jest wykonywany -> zarówno deklaracja, jak i kod są interpretowane, a wiele funkcji Pythona jest opartych na tym.