Czy mógłbyś mi wyjaśnić, jaka jest różnica między dzwonieniem
python -m mymod1 mymod2.py args
i
python mymod1.py mymod2.py args
Wydaje się, że w obu przypadkach mymod1.py
nazywa się i sys.argv
jest
['mymod1.py', 'mymod2.py', 'args']
Więc do czego służy -m
przełącznik?
python
command-line
module
package
Charles Brunet
źródło
źródło
-m
wydaje się, że wyszukujęmymod1
w domyślnej ścieżce biblioteki. Przykład:python -m SimpleHTTPServer
działa, alepython SimpleHTTPServer
kończy się niepowodzeniem zcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
.Odpowiedzi:
Pierwsza linia
Rationale
sekcji PEP 338 mówi:Możesz więc w ten sposób określić dowolny moduł w ścieżce wyszukiwania Pythona, a nie tylko pliki w bieżącym katalogu. Masz rację, że
python mymod1.py mymod2.py args
ma dokładnie ten sam efekt. W pierwszym wierszuScope of this proposal
sekcji podano:Z
-m
bardziej jest to możliwe, jak pracować z modułami, które są częścią pakietu, itp to co reszta PEP 338 chodzi. Przeczytaj to, aby uzyskać więcej informacji.źródło
-m
topython -m SimpleHTTPServer
. Naprawdę przydatne, gdy chcę udostępnić niektóre pliki bez użycia dysku flash USB.python -m http.server
i nadal jest super!python -m package.subpackage.module
i normalna maszyna do rozwiązywania problemów będzie używana, nie musisz wskazywać dokładnego.py
pliku. 2) Możliwe jest wykonanie względnego importu z uruchamianego modułu bez żadnych obejść, ponieważ jego pakiet zostanie załadowany po drodze. 3) Absolutne importowanie będzie oparte na bieżącym katalogu, a nie na katalogu, w którym.py
znajduje się plik (''
jest na początkusys.path
, a nie/path/to/my
, jeśli skrypt jest w/path/to/my/script.py
).__main__.py
plik. Większość nie pęknie i na przykładpython -m sys 'print(sys.version)'
nie działa zpython: No code object available for sys
. Zaproponuj, abyś wyjaśnił to w odpowiedzi.Warto wspomnieć, że działa to tylko wtedy, gdy pakiet ma plik.
__main__.py
W przeciwnym razie ten pakiet nie może zostać wykonany bezpośrednio.Interpreter Pythona będzie szukał
__main__.py
pliku w ścieżce pakietu do wykonania. Jest to równoważne z:Treść zostanie wykonana po:
źródło
Pomimo tego, że zadawano to pytanie i odpowiadano na nie kilka razy (np. Tutaj , tutaj , tutaj i tutaj ), moim zdaniem żadna istniejąca odpowiedź nie oddaje w pełni ani zwięźle wszystkich implikacji
-m
flagi. Dlatego poniższe postarają się ulepszyć to, co było wcześniej.Wprowadzenie (TLDR)
-m
Komenda robi wiele rzeczy, nie wszystkie z nich muszą być potrzebne przez cały czas. W skrócie: (1) pozwala na wykonywanie skryptów Pythona za pomocą nazwy modułu zamiast nazwy pliku (2) pozwala wybrać katalog do dodania wsys.path
celuimport
rozwiązania problemu oraz (3) umożliwia wykonywanie skryptów Pythona z relatywnymi importami z wiersza poleceń .Czynności wstępne
Aby wyjaśnić
-m
flagę, musimy najpierw wyjaśnić trochę terminologii.Po pierwsze, podstawowa jednostka organizacyjna Pythona jest nazywana modułem . Moduły występują w jednym z dwóch rodzajów: moduły kodu i moduły pakietów. Moduł kodu to dowolny plik zawierający kod wykonywalny w języku Python. Moduł pakietu to katalog zawierający inne moduły (moduły kodu lub moduły pakietów). Najpopularniejszym typem modułów kodu są
*.py
pliki, podczas gdy najpopularniejszym typem modułów pakietu są katalogi zawierające__init__.py
plik.Po drugie, wszystkie moduły można jednoznacznie zidentyfikować na dwa różne sposoby:
<modulename>
i<filename>
. Moduły są najczęściej identyfikowane przez nazwę modułu w kodzie Pythona (np.import <modulename>
) I nazwę pliku w wierszu poleceń (nppython <filename>
.). Wszystkie interpretery Pythona mogą konwertować nazwy modulów na nazwy plików za pomocą zestawu dobrze zdefiniowanych reguł. Reguły te zależą odsys.path
zmiennej i dlatego mapowanie można zmienić, zmieniając tę wartość (więcej informacji na temat tego, jak to się robi, znajduje się w PEP 302 ).Po trzecie, wszystkie moduły (zarówno kod, jak i pakiet) mogą zostać wykonane (przez co rozumiemy kod powiązany z modułem zostanie oceniony przez interpreter Pythona). W zależności od metody wykonania i typu modułu, jaki kod jest oceniany i kiedy, może się nieco zmienić. Na przykład, jeśli wykonuje się moduł pakietu za pośrednictwem,
python <filename>
to<filename>/__init__.py
zostanie ocenione, a po nim<filename>/__main__.py
. Z drugiej strony, jeśli ktoś wykonuje ten sam moduł pakietu za pośrednictwem,import <modulename>
to tylko pakiety__init__.py
zostaną wykonane.Rozwój historyczny
-m
Flaga -m została po raz pierwszy wprowadzona w Pythonie 2.4.1 . Początkowo jego jedynym celem było zapewnienie alternatywnych sposobów identyfikacji modułu Pythona do wykonania. Oznacza to, że gdybyśmy znali zarówno moduł, jak
<filename>
i<modulename>
dla modułu, następujące dwa polecenia byłyby równoważne:python <filename> <args>
ipython -m <modulename> <args>
. Ponadto, zgodnie z PEP 338, ta iteracja-m
działała tylko z nazwami modulów najwyższego poziomu (tj. Modułami, które można znaleźć bezpośrednio w sys.path bez żadnych pakietów pośredniczących).Wraz z zakończeniem PEP 338
-m
funkcjonalność została rozszerzona na wsparcie<modulename>
reprezentacji poza najlepszych moduleNames szczebla. Oznaczało to, że nazwy takie jakhttp.server
były teraz w pełni obsługiwane. To ulepszenie oznaczało również, że wszystkie pakiety w module zostały załadowane (tj. Wszystkie__init__.py
pliki pakietów zostały ocenione) wraz z samym modułem.Ostatnie główne ulepszenie funkcji
-m
przyszło wraz z PEP 366 . Dzięki tej aktualizacji-m
zyskał możliwość obsługi nie tylko importu bezwzględnego, ale także jawnego importu względnego. Osiągnięto to poprzez zmodyfikowanie__package__
zmiennej dla nazwanego modułu w-m
poleceniu.Przypadków użycia
Istnieją dwa godne uwagi przypadki użycia flagi -m:
Aby uruchomić moduły z wiersza poleceń, dla których można nie znać ich nazw plików. Ten przypadek użycia wykorzystuje fakt, że interpreter Pythona wie, jak przekonwertować nazwy modulów na nazwy plików. Jest to szczególnie korzystne, gdy chce się uruchomić moduły stdlib lub moduł innej firmy z wiersza poleceń. Na przykład, bardzo niewiele osób zna nazwę pliku
http.server
modułu, ale większość ludzi zna jego nazwę modułu, więc możemy go uruchomić z wiersza poleceń za pomocąpython -m http.server
.Aby wykonać lokalny pakiet zawierający bezwzględne importy bez konieczności instalowania go. Ten przypadek użycia jest szczegółowo opisany w PEP 338 i wykorzystuje fakt, że bieżący katalog roboczy jest dodawany do
sys.path
katalogu modułu, a nie do niego. Ten przypadek użycia jest bardzo podobny do używaniapip install -e .
do instalowania pakietu w trybie tworzenia / edycji.Niedociągnięcia
Pomimo wszystkich ulepszeń wprowadzonych na
-m
przestrzeni lat, nadal ma jedną poważną wadę - może wykonywać tylko moduły kodu napisane w Pythonie (tj. * .Py). Na przykład, jeśli-m
jest używany do wykonania skompilowanego modułu kodu w C, zostanie wygenerowany następujący błądNo code object available for <modulename>
(zobacz tutaj, aby uzyskać więcej informacji).Szczegółowe porównania
Efekty wykonania modułu za pomocą polecenia Pythona (tj.
python <filename>
):sys.path
jest modyfikowany, aby uwzględnić ostateczny katalog w<filename>
__name__
jest ustawione na'__main__'
__package__
jest ustawione naNone
__init__.py
nie jest oceniany dla żadnego pakietu (w tym własnego dla modułów pakietu)__main__.py
jest oceniany dla modułów pakietu; kod jest oceniany pod kątem modułów kodu.Efekty wykonania modułu poprzez instrukcję importu (tj.
import <modulename>
):sys.path
nie jest w żaden sposób modyfikowany__name__
jest ustawiona na absolutną formę<modulename>
__package__
jest ustawiony na bezpośredni pakiet nadrzędny w<modulename>
__init__.py
jest oceniany dla wszystkich pakietów (w tym własnego dla modułów pakietów)__main__.py
nie jest oceniany dla modułów pakietu; kod jest oceniany pod kątem modułów koduEfekty wykonania modułu za pomocą flagi -m (tj.
python -m <modulename>
):sys.path
jest modyfikowany w celu uwzględnienia bieżącego katalogu__name__
jest ustawione na'__main__'
__package__
jest ustawiony na bezpośredni pakiet nadrzędny w<modulename>
__init__.py
jest oceniany dla wszystkich pakietów (w tym własnego dla modułów pakietów)__main__.py
jest oceniany dla modułów pakietu; kod jest oceniany pod kątem modułów koduWniosek
-m
Flaga jest w swej najprostszej, środki do wykonywania skryptów Pythona z linii poleceń za pomocą moduleNames zamiast nazw plików. Dodatkowo-m
zapewnia dodatkową funkcjonalność, która łączy mocimport
instrukcji (np. Obsługę jawnych importów względnych i automatycznej__init__
oceny pakietów ) z wygodą wiersza poleceń Pythona.źródło
python -m packagename
jak wspomniano tutaj: stackoverflow.com/a/53772635/1779091