2010-10-28 16 views
400

Powiel możliwe:
What does if __name__== "__main__" do?Dlaczego użyć def main()?

Widziałem kilka próbek kodu i samouczki, które używają

def main(): 
    # my code here 

if __name__ == "__main__": 
    main() 

ale dlaczego? Czy jest jakiś powód, dla którego nie definiujesz swoich funkcji na górze pliku, a następnie piszesz pod nim kod? tj.

def my_function() 
    # my code here 

def my_function_two() 
    # my code here 

# some code 
# call function 
# print(something) 

Zastanawiam się, czy nie ma rymów do głównego?

+2

Zobacz http://stackoverflow.com/questions/419163/what-does-if-name-main-do – gimel

+8

stackoverflow.com/questions/419163/what-does-if-name-main-do does nie odpowiadam na całe pytanie. – Johnsyweb

+4

Czego rzekomy duplikat nie odpowiada: posiadanie funkcji main() (zamiast zapisywania całego kodu w bloku "if __name__") jest przydatne, ponieważ pozwala uniknąć przypadkowego utworzenia zmiennych globalnych, które mogłyby wpłynąć na inne funkcje. – slowdog

Odpowiedz

465

Bez głównego sentinela kod byłby wykonany, nawet jeśli skrypt zostałby zaimportowany jako moduł.

+121

Warto również zauważyć, że posiadanie Funkcja 'main()' umożliwia uruchomienie tego kodu za pomocą: 'import module; module.main() '. Jeśli kod znajduje się w bloku 'if', nie można go uruchomić z innego źródła. – FogleBird

7

Rozważ drugi scenariusz. Jeśli zaimportujesz go w innym, instrukcje, jak na "poziomie globalnym", zostaną wykonane.

72

jeśli zawartość foo.py

print __name__ 
if __name__ == '__main__': 
    print 'XXXX' 

Plik foo.py można stosować na dwa sposoby.

  • importowany w innym pliku: import foo

W tym przypadku __name__ jest foo, sekcja kod nie zostanie wykonany i nie drukuje XXXX.

  • wykonywane bezpośrednio: python foo.py

Gdy jest wykonywany bezpośrednio, __name__ jest taka sama jak __main__ a kod w tej sekcji jest wykonywany i drukuje XXXX

Jednym z wykorzystaniem tej funkcji do pisania różnego rodzaju testów jednostkowych w ramach tego samego modułu.

+0

Chociaż ta odpowiedź jest mniej głosowana niż niektóre inne, ale wyjaśniła to bardzo wyraźnie. Czytam [tę odpowiedź] (http://stackoverflow.com/a/419185/2455888) wcześniej, ale twoja jest dobrze wyjaśniona. +1 – haccks

15

"What does if __name__==“__main__”: do?" został już odebrany.

Posiadanie main()funkcję pozwala nazwać jego funkcjonalność jeśli import moduł. Główną (nie gra słów, którą zamierzono) korzyścią z tego (IMHO) jest to, że możesz je przetestować w jednostce.

+1

2 pytania o tę samą odpowiedź nie czyni ich duplikatami – bubakazouba

+3

@bubakazouba: Zgadzam się. Nie oznaczałem tego pytania jako duplikatu. * Część * tego pytania ma naprawdę dobrą odpowiedź, nie widziałem sensu dublowania odpowiedzi. Odpowiadałem * resztę * pytania. – Johnsyweb

183

Wszyscy inni już odpowiedzieli, ale myślę, że nadal mam coś jeszcze do dodania.

Przyczyny mieć że if oświadczenie wzywające main() (w przypadkowej kolejności):

  • inne języki (takie jak C i Java) mają main() funkcji, która jest wywoływana, gdy program jest wykonywany. Korzystając z tego if, możemy sprawić, aby Python zachowywał się tak jak oni, który jest bardziej znany dla wielu osób.

  • Kod będzie czystszy, łatwiejszy do odczytania i lepiej zorganizowany. (tak, wiem, że to jest subiektywne)

  • To będzie możliwe do import, że kod Pythona jako moduł bez nieprzyjemnych skutków ubocznych.

    • Oznacza to, że będzie można przeprowadzić testy na tym kodzie.

    • Oznacza to, że możemy zaimportować ten kod do interaktywnej powłoki Pythona i przetestować/debugować/uruchomić.

  • Zmienne wewnątrz def mainlokalnej, natomiast poza nim są globalnego. Może to wprowadzić kilka błędów i nieoczekiwanych zachowań.

Ale jesteś nie wymaga napisać main() funkcję i wywołać ją wewnątrz instrukcji if.

Ja zwykle zaczynam pisać małe skrypty jednorazowe bez żadnej funkcji. Jeśli skrypt będzie wystarczająco duży, lub jeśli poczuję, że umieszczenie całego kodu wewnątrz funkcji przyniesie mi korzyść, wówczas zmienię kod i zrobię to. Dzieje się tak również, gdy piszę skrypty bash.

Nawet jeśli umieścisz kod w głównej funkcji, nie musisz pisać tego dokładnie. Zgrabny zmienność może być:

import sys 

def main(argv): 
    # My code here 
    pass 

if __name__ == "__main__": 
    main(sys.argv) 

Oznacza to, że można zadzwonić main() z innych skryptów (lub interaktywnej powłoki) uboczny parametrów niestandardowych. Może to być przydatne w testach jednostkowych lub podczas przetwarzania wsadowego. Ale pamiętaj, że powyższy kod będzie wymagał parsowania argv, więc może lepiej będzie użyć innego wywołania, które przekazuje parametry już przeanalizowane.

W aplikacji obiektowej Pisałem kod wyglądał tak:

class MyApplication(something): 
    # My code here 

if __name__ == "__main__": 
    app = MyApplication() 
    app.run() 

Tak, nie krępuj się napisać kod, który lepiej pasuje do ciebie. :)

+0

Jedną z zalet wywoływania 'main' z' sys.argv' jako parametr, jak pokazano tutaj, jest to, że to podejście działa dobrze z modułem 'argparse' (który, IMO, jest * właściwą metodą * do obsługi argumentów linii poleceń) . Wszystko, co musisz zrobić inaczej, to przekazanie 'argv' do' parse_args' w 'main'. – jkt123