Können Sie mir erklären, was der Unterschied zwischen Anrufen ist?
python -m mymod1 mymod2.py args
und
python mymod1.py mymod2.py args
Es scheint in beiden Fällen mymod1.py
heißt und sys.argv
ist
['mymod1.py', 'mymod2.py', 'args']
Wofür ist der -m
Schalter?
python
command-line
module
package
Charles Brunet
quelle
quelle
-m
zu suchen scheintmymod1
. Beispiel:python -m SimpleHTTPServer
funktioniert, während mitpython SimpleHTTPServer
scheitertcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
.Antworten:
Die erste Zeile des
Rationale
Abschnitts von PEP 338 lautet:Auf diese Weise können Sie jedes Modul im Python-Suchpfad angeben, nicht nur Dateien im aktuellen Verzeichnis. Sie haben Recht, das
python mymod1.py mymod2.py args
hat genau den gleichen Effekt. In der ersten Zeile desScope of this proposal
Abschnitts heißt es:Mit
-m
mehr ist möglich, wie mit Modulen zu arbeiten, die Teil eines Pakets sind usw. Darum geht es im Rest von PEP 338. Lesen Sie es für weitere Informationen.quelle
-m
istpython -m SimpleHTTPServer
. Sehr praktisch, wenn ich einige Dateien ohne Verwendung eines USB-Flash-Laufwerks freigeben muss.python -m http.server
dies immer noch fantastisch ist!python -m package.subpackage.module
und die normale Auflösungsmaschine wird verwendet, Sie müssen nicht auf die genaue.py
Datei hinweisen . 2) Es ist möglich, relative Importe aus dem ausgeführten Modul ohne Problemumgehungen durchzuführen, da das Paket unterwegs geladen wird. 3) Absolute Importe basieren auf Ihrem aktuellen Verzeichnis, nicht auf dem Verzeichnis, in dem sich die.py
Datei befindet (''
befindet sich am Anfang vonsys.path
und nicht/path/to/my
, wenn sich das Skript befindet/path/to/my/script.py
).__main__.py
Datei haben. Die meisten nicht und werden brechen, zBpython -m sys 'print(sys.version)'
scheitert mitpython: No code object available for sys
. Schlagen Sie vor, dass Sie dies in der Antwort klarstellen.Erwähnenswert ist, dass dies nur funktioniert, wenn das Paket eine Datei enthält.
__main__.py
Andernfalls kann dieses Paket nicht direkt ausgeführt werden.Der Python-Interpreter sucht im Paketpfad nach einer
__main__.py
Datei, die ausgeführt werden soll. Es ist äquivalent zu:Der Inhalt wird ausgeführt nach:
quelle
Obwohl diese Frage mehrmals gestellt und beantwortet wurde (z. B. hier , hier , hier und hier ), erfasst meiner Meinung nach keine vorhandene Antwort alle Implikationen der
-m
Flagge vollständig oder präzise . Daher wird im Folgenden versucht, das bisherige zu verbessern.TLDR
Der
-m
Befehl erledigt viele Dinge, die nicht unbedingt immer benötigt werden. Kurz gesagt: (1) ermöglicht die Ausführung von Python-Skripten über den Modulnamen anstelle des Dateinamens. (2) ermöglicht die Auswahl eines Verzeichnisses, dassys.path
zurimport
Auflösung hinzugefügt werden soll, und (3) ermöglicht, dass Python-Skripte mit relativen Importen so funktionieren, als ob sie es wären angerufen überimport
.Vorbereitungen
Um die Bedeutung der
-m
Flagge zu verstehen , muss eine kleine Terminologie klargestellt werden.Erstens werden Dateien, die Python ausführen kann, als Module bezeichnet. Normalerweise sind die Module, die uns interessieren,
*.py
Dateien, aber nicht immer. Beispielsweise ist es möglich, Python-Module für leistungskritischen Code in C zu schreiben. Diese Unterscheidung wird später wichtig. Im Moment reicht es zu wissen, dass Nicht-Paket-Module Dateien sind.Zweitens identifiziert Python Module über eine eindeutige
<modulename>
Kennung (zimport <modulename>
. B. ). Für jedes Unikat<modulename>
gibt es auch irgendwo auf dem Computer eine eindeutige Datei mit einem eigenen Unikat<filename>
. Python Dolmetscher folgen einer Reihe von gut definierten Regeln gebaut umsys.path
eine zur Karte<modulename>
zu einem<filename>
(mehr darüber , wie dies geschehen ist , siehe PEP 302 ).Historische Entwicklung von
-m
Mit Blick auf die Vorbereitungen
-m
kann im einfachsten Sinne erklärt werden, dass Python angewiesen wird, ein Modul zu finden, über das ausgeführt werden soll,<modulename>
anstatt<filename>
. Das heißt, wenn entweder ein<filename>
oder<modulename>
für dasselbe Modul gegeben ist, sind die folgenden zwei Befehle äquivalentpython <filename>
oderpython -m <modulename>
.In der ursprünglichen Version 2.4.1, in
-m
der hinzugefügt wurde, wurden lediglich Module von gesucht und ausgeführt<modulename>
(wobei zusätzlich das aktuelle Verzeichnis hinzugefügt wurde,sys.path
damit auch lokale Module gefunden werden konnten). Gemäß PEP 338 wurde auch die ursprüngliche Implementierung eingeschränkt, so dass-m
keine Modulnamen in Paketen referenziert werden konnten (dh die Version 2.4.1 würde den Modulnamen nicht unterstützen,http.server
aber unterstützentimeit
).Mit PEP 338 wurde die
-m
Funktionalität erweitert, um<modulename>
Darstellungen in Paketen zu unterstützen. Dies bedeutete Namen, wiehttp.server
sie jetzt vollständig von unterstützt wurden-m
. Diese Erweiterung bedeutet auch , dass alle Pakete in einem Modulnamen geladen werden mußten (dh die Pakete__init__.py
wurden Dateien ausgeführt), zusammen mit dem Modul selbst, falls die Pakete ihr modifizierten__path__
in__init__.py
.Ein bemerkenswerter Anwendungsfall, der
-m
nach PEP 338 unterstützt wurde, waren absolute Importanweisungen in benutzerdefinierten Paketen, ohne dass ein Paket installiert werden musstesys.path
. Dies kann erreicht werden, indem einfach-m
Skriptdateien aus dem Stammverzeichnis des benutzerdefinierten Projekts geladen werden (da das Stammverzeichnis dann hinzugefügt wirdsys.path
).Die letzte wichtige Funktionserweiterung für
-m
kam mit PEP 366 . Mit diesem Update wurde-m
die Möglichkeit gewonnen, nicht nur absolute Importe, sondern auch explizite relative Importe zu unterstützen. Dies wurde erreicht, indem die__package__
Variable für das benannte Modul im-m
Befehl geändert wurde.Mit all den oben genannten Verbesserungen
-m
weist es immer noch ein großes Manko auf. Es können nur Module ausgeführt werden, die in Python (dh*.py
) geschrieben sind. Wenn ein Modulname, der sich auf ein C-kompiliertes Modul bezieht, an-m
den folgenden Fehler übergeben wird , wird der folgende Fehler erzeugtNo code object available for <modulename>
.Vergleich
-m
mit anderen AusführungsmethodenIm Kern ist das
-m
Flag ein Mittel, um Python-Skripte über den Modulnamen und nicht über den Dateinamen auszuführen. Aus diesem Grund vergleichen wir es mit den beiden anderen bekannteren Methoden zur Ausführung von Modulen: (1) Dateiname mit dempython
Befehl und (2) Modulname mit derimport
Anweisung.Auswirkungen der Dateinamenausführung mit dem
python
Befehl (dhpython <filename>
):sys.path
so geändert, dass der Speicherort des Moduls in die Importauflösung einbezogen wird__name__
Variable des Moduls ist auf gesetzt'__main__'
__package__
Variable des Moduls ist auf gesetztNone
__init__.py
Für übergeordnete Pakete in werden keine Dateien ausgeführt<filename>
Auswirkungen der Ausführung von Modulnamen mit der
import
Anweisung (dhimport <modulename>
):sys.path
ist nicht für den Import Auflösung in keiner Weise verändert__name__
Variable des Moduls wird auf ihren absoluten Modulnamen gesetzt__package__
Variable des Moduls wird auf das enthaltende Paket in gesetzt<modulename>
__init__.py
Dateien werden für übergeordnete Pakete in ausgeführt<modulename>
Auswirkungen der Ausführung von Modulnamen mit dem
-m
Flag (dhpython -m <modulename>
):sys.path
so geändert, dass das aktuelle Verzeichnis in die Importauflösung aufgenommen wird__name__
Variable des Moduls ist auf gesetzt'__main__'
__package__
Variable des Moduls wird auf das enthaltende Paket in gesetzt<modulename>
__init__.py
Dateien werden für übergeordnete Pakete in ausgeführt<modulename>
Zusammenfassung
Das
-m
Flag ist einfach eine alternative Möglichkeit, ein Python-Skript über den Modulnamen und nicht über den Dateinamen auszuführen. Aus diesem Grund muss man zumindest ein kleines Verständnis dafür haben, wie Python Modulnamen Dateinamen zuordnet, um sie voll ausnutzen zu können. Mit diesem Verständnis erhält man jedoch ein leistungsstarkes neues Tool, das Funktionen vonimport
Anweisungen (z. B. Unterstützung für explizite relative Importanweisungen) mit der Bequemlichkeit von Befehlszeilenanweisungen kombiniertpython
.quelle
python -m packagename
: stackoverflow.com/a/53772635/1779091