W tym przewodniku zrozumiesz funkcjonalność i znaczenie if __name__ == '__main__’ w Pythonie.
Czy kiedykolwiek przeglądałeś bazę kodu Pythona z różnymi modułami?
Jeśli tak, prawdopodobnie spotkałbyś się z warunkowym __name__ == '__main__’ w jednym lub kilku modułach. W ciągu następnych kilku minut wyjaśnimy, co oznacza powyższy warunek warunkowy i przyjrzymy się przykładowi, w którym może to być pomocne.
Zaczynajmy!
Spis treści:
Jakie jest znaczenie __name__ w Pythonie?
W Pythonie moduł jest plikiem .py zawierającym definicje funkcji, zestaw wyrażeń do oceny i nie tylko. Na przykład, jeśli mamy plik o nazwie hello_world.py, nazywamy go plikiem hello_world.py lub modułem hello_world.
Kiedy uruchamiasz moduł Pythona, interpreter Pythona ustawia wartości kilku specjalnych zmiennych przed wykonaniem: __name__ jest jedną z nich. Kluczem do zrozumienia znaczenia __name__ jest zrozumienie, jak działają importy w Pythonie.
📁 Pobierz kod do tej sekcji tutaj.
Udaj się do folderu przykład-1. Mamy plik module1.py. Zmienna __name__ znajduje się w przestrzeni nazw bieżącego modułu.
Ten moduł wypisuje wiersz, po którym następuje wartość zmiennej __name__.
# example-1/module1.py print("This is module1.") print(f"The __name__ variable of module 1 is: {__name__}.")
Teraz uruchommy module1 z wiersza poleceń.
$ python module1.py
Na wyjściu widzimy, że zmienna __name__ jest ustawiona na __main__.
This is module1. The __name__ variable of module 1 is: __main__.
Importowanie modułów w Pythonie
Oprócz uruchomienia modułu Pythona, czasami możesz chcieć użyć funkcjonalności z innego modułu Pythona wewnątrz bieżącego modułu. Python ułatwia to poprzez importy.
Importy umożliwiają ponowne wykorzystanie funkcji innego modułu — poprzez zaimportowanie go do zakresu bieżącego modułu — bez konieczności przepisywania kodu.
Plik module2.py zawiera następujące elementy. W środku zaimportowaliśmy moduł1. moduł2.
# example-1/module2.py import module1 # module1 is imported print(f"This is module2") print(f"The __name__ variable of module2 is: {__name__}.")
Uruchamiamy module2.py i obserwujemy wyjście.
$ python module2.py
W poniższym wyjściu:
- Widzimy, że module1 jest uruchamiany pod maską, gdy importujemy go do modułu module2, a odpowiednie dane wyjściowe są drukowane.
- Ale tym razem zmienna __name__ to nie __main__, ale moduł1.
- Ponieważ uruchomiliśmy module2 bezpośrednio, zmienna __name__ odpowiadająca modułowi to teraz __main__.
Output This is module1. The __name__ variable of module 1 is: module1. This is module2 The __name__ variable of module2 is: __main__.
💡 Kluczowa idea:
– Jeśli moduł jest uruchamiany bezpośrednio, jego zmienna __name__ jest ustawiona na __main__.
– Jeśli moduł jest importowany wewnątrz innego modułu, jego __name__ jest ustawiana na nazwę modułu.
Przykład, jeśli __name__==’__main__’ w Pythonie
W tej sekcji zobaczymy praktyczny przypadek użycia warunkowego if __name__ == '__main__’. Zdefiniujemy prostą funkcję, a następnie napiszemy testy jednostkowe, aby sprawdzić, czy funkcja działa zgodnie z oczekiwaniami.
📁 Pobierz kod i postępuj zgodnie z instrukcjami.
Kod do tej sekcji można znaleźć w folderze example-2.
Tutaj add.py jest plikiem Pythona, który zawiera definicję funkcji add_ab(). Funkcja add_ab() przyjmuje dowolne dwie liczby i zwraca ich sumę.
# example-2/add.py def add_ab(a,b): return a + b
Wykorzystamy moduł testów jednostkowych Pythona do przetestowania funkcji add_ab().
Pisanie przypadków testowych dla funkcji Pythona
Spójrz na poniższy fragment kodu, zawierający zawartość modułu test_add.
# example-2/test_add.py import unittest from add import add_ab class TestAdd(unittest.TestCase): def test_add_23(self): self.assertEqual(add_ab(2,3), 5) def test_add_19(self): self.assertEqual(add_ab(1,9), 10) def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), -6)
Powyższy kod wykonuje następujące czynności:
- Importuje wbudowany moduł testów jednostkowych Pythona
- Importuje funkcję add_ab() z modułu add
- Definiuje klasę testową TestAdd i zestaw przypadków testowych jako metody w klasie testowej
Aby skonfigurować testy jednostkowe dla kodu, należy najpierw zdefiniować klasę testową, która dziedziczy po unittest.TestCase. Wszystkie przypadki testowe powinny być określone jako metody wewnątrz klasy i powinny zaczynać się od test_.
Uwaga: Jeśli nie nazwiesz metod jako test_
Teraz spróbujmy uruchomić moduł test_add z terminala.
$ python test_add.py
Zobaczysz, że nie ma danych wyjściowych i żaden z testów nie został uruchomiony.
Dlaczego tak jest?🤔
Dzieje się tak dlatego, że aby uruchomić testy jednostkowe, powinieneś uruchomić unittest jako główny moduł podczas uruchamiania test_add.py, używając poniższego polecenia.
$ python -m unittest test_add.py
Po uruchomieniu powyższego szczegółowego polecenia widzimy, że wszystkie trzy testy zakończyły się pomyślnie.
Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Jednak wygodniej będzie uruchamiać testy, gdy ten moduł test_add jest uruchomiony, tak? Nauczmy się, jak to zrobić w następnej sekcji.
Użycie if __name__ == '__main__’ do uruchomienia testu jednostkowego jako modułu głównego
Jeśli chcesz uruchomić wszystkie testy jednostkowe, gdy moduł działa bezpośrednio, możesz dodać warunek.
# example-2/test_add.py import unittest from add import add_ab class TestAdd(unittest.TestCase): def test_add_23(self): self.assertEqual(add_ab(2,3), 5) def test_add_19(self): self.assertEqual(add_ab(1,9), 10) def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), -6) # Run unittest as the main module if __name__ == '__main__': unittest.main()
Warunek w powyższym fragmencie kodu mówi interpreterowi Pythona: Jeśli ten moduł jest uruchamiany bezpośrednio, uruchom znajdujący się w nim kod. test_jednostki.main().
Możesz uruchomić moduł test_add po dodaniu powyższych dwóch linii kodu.
$ python test_add.py
▶️ Bezpośrednie uruchomienie modułu dodawania testu uruchamia teraz wszystkie trzy zdefiniowane przez nas testy.
Output ... ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Powyższe dane wyjściowe OK wskazują, że wszystkie testy zostały wykonane pomyślnie. Trzy kropki… wskazują, że przeprowadzono trzy testy i wszystkie zaliczone.
Teraz zmieńmy oczekiwaną wartość zwracaną test_add_1_minus7 na 8. Ponieważ funkcja zwraca – w tym przypadku 6, powinien być jeden test zakończony niepowodzeniem.
def test_add_1_minus7(self): self.assertEqual(add_ab(1,-7), 8)
Jak widać na poniższym wyjściu, otrzymujemy .F., z trzech testów, wzór jeden z nich nie powiódł się (drugi test), a w śledzeniu otrzymujemy AssertionError stwierdzający – 6 != 8.
Output .F. ====================================================================== FAIL: test_add_1_minus7 (__main__.TestAdd) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_add.py", line 12, in test_add_1_minus7 self.assertEqual(add_ab(1,-7), 8) AssertionError: -6 != 8 ---------------------------------------------------------------------- Ran 3 tests in 0.021s FAILED (failures=1)
Ważną rzeczą, na którą należy zwrócić uwagę, jest to, że testy niekoniecznie są uruchamiane w tej samej kolejności, w jakiej zostały określone w klasie testów. W powyższym przykładzie test_add_1_minus7 jest zdefiniowany jako trzecia metoda w klasie testowej, ale odpowiedni test został uruchomiony jako drugi.
Podsumowując
Mam nadzieję, że ten samouczek pomógł ci zrozumieć, jak warunek warunkowy if __name__ == '__main__’ działa w Pythonie.
Oto krótkie podsumowanie najważniejszych wniosków:
- Interpreter Pythona ustawia zmienną __name__ przed wykonaniem skryptu Pythona.
- Kiedy uruchamiasz moduł bezpośrednio, wartość __name__ to __main__.
- Kiedy importujesz moduł do innego skryptu Pythona, wartością __name__ jest nazwa modułu.
- Możesz użyć if __name__ == '__main__’ do kontrolowania wykonania i które części modułu są uruchamiane odpowiednio podczas bezpośredniego i importowanego przebiegu.
Następnie zapoznaj się z tym szczegółowym przewodnikiem po zestawach Pythona. Miłej nauki!🎉