Über uns
Da Python eine sehr beliebte Programmiersprache ist und die meisten Betriebssysteme sowie viele Bibliotheken unterstützt, die die Verarbeitung von Befehlszeilenargumenten vereinfachen, wird es häufig zum Erstellen von Befehlszeilentools für viele Zwecke verwendet. Diese Tools können von einfachen CLI-Apps bis hin zu komplexeren Apps wie AWS reichen. awscli Werkzeug.
Komplexe Tools wie dieses werden typischerweise vom Benutzer über gesteuert Kommandozeilenargumente, wodurch der Benutzer bestimmte Befehle verwenden, Optionen festlegen und mehr verwenden kann. Diese Optionen könnten das Tool beispielsweise anweisen, zusätzliche Informationen auszugeben, Daten aus einer bestimmten Quelle zu lesen oder die Ausgabe an einen bestimmten Ort zu senden.
Im Allgemeinen werden Argumente je nach Betriebssystem unterschiedlich an CLI-Tools übergeben:
- Unix-ähnlich:
-
gefolgt von einem Buchstaben, wie-h
, oder--
gefolgt von einem Wort, wie--help
- Windows:
/
gefolgt von einem Buchstaben oder einem Wort/help
Diese unterschiedlichen Ansätze sind historisch bedingt. Viele Programme auf Unix-ähnlichen Systemen unterstützen sowohl die einfache als auch die doppelte Bindestrich-Notation. Die Schreibweise mit einem einzelnen Bindestrich wird meist bei Einzelbuchstabenoptionen verwendet, während doppelte Bindestriche eine besser lesbare Optionsliste darstellen, was besonders für komplexe Optionen nützlich ist, die expliziter sein müssen.
Note: In diesem Artikel konzentrieren wir uns ausschließlich auf das Unix-ähnliche Format von -
und --
.
Bedenken Sie, dass sowohl der Name als auch die Bedeutung eines Arguments spezifisch für ein Programm sind – es gibt keine allgemeine Definition, außer ein paar gängigen Konventionen wie --help
Weitere Informationen zur Verwendung des Tools finden Sie hier. Als Entwickler eines Python-Skripts entscheiden Sie, welche Argumente Sie dem Aufrufer bereitstellen und was diese tun. Dies erfordert eine ordnungsgemäße Bewertung.
Je länger Ihre Liste verfügbarer Argumente wird, desto komplexer wird Ihr Code bei dem Versuch, diese genau zu analysieren. Glücklicherweise gibt es in Python eine Reihe von Bibliotheken, die Ihnen dabei helfen. Wir werden einige der gängigsten Lösungen behandeln, die von „Do-it-yourself“ bis hin zu reichen sys.argv
, zum „Done-for-you“-Ansatz mit argparse
.
Umgang mit Befehlszeilenargumenten mit Python
Python 3+ und das umliegende Ökosystem unterstützen eine Reihe unterschiedlicher Möglichkeiten zur Handhabung von Befehlszeilenargumenten. Es gibt viele Bibliotheken, die das Parsen von Befehlszeilenargumenten erleichtern.
Die integrierte Möglichkeit besteht darin, die zu verwenden sys
Modul. In Bezug auf Namen und Verwendung bezieht es sich direkt auf die C-Bibliothek (libc
).
Der zweite Weg ist der getopt
Modul, das sowohl kurze als auch lange Optionen verarbeitet, einschließlich der Auswertung der Parameterwerte.
Das argparse-Modul, die sich aus dem optparse
Modul (verfügbar bis Python 2.7).
Das docopt
Modul, das ist verfügbar auf GitHubermöglicht auch die gleiche Funktionalität.
Vor kurzem hat die absl
Auch die Bibliothek als Mittel zum Ersatz hat an Bedeutung gewonnen optparse
und getopt()
.
Jede dieser Möglichkeiten hat ihre Vor- und Nachteile, daher lohnt es sich, jede einzelne davon zu prüfen, um herauszufinden, welche Ihren Anforderungen am besten entspricht.
Das sys-Modul
Dies ist ein Basismodul, das seit den Anfängen mit Python ausgeliefert wurde. Es verfolgt einen sehr ähnlichen Ansatz wie die Verwendung der C-Bibliothek argc
/argv
um auf die Argumente zuzugreifen. Der sys-Modul implementiert die Befehlszeilenargumente in einer einfachen Listenstruktur mit dem Namen sys.argv
.
Jedes Listenelement stellt ein einzelnes Argument dar. Das erste Element in der Liste,
sys.argv[0]
, ist der Name des Python-Skripts. Die restlichen Listenelemente,sys.argv[1]
zusys.argv[n]
, sind die Befehlszeilenargumente 2 bis n.
Als Trennzeichen zwischen den Argumenten wird ein Leerzeichen verwendet. Argumentwerte, die ein Leerzeichen enthalten, müssen in Anführungszeichen gesetzt werden, damit sie ordnungsgemäß analysiert werden können sys
.
Das Äquivalent von argc
ist nur die Anzahl der Elemente in der Liste. Um diesen Wert zu erhalten, verwenden Sie Python len()
Operator. Wir werden dies später in einem Codebeispiel zeigen.
Drucken des ersten CLI-Arguments
In diesem ersten Beispiel bestimmt unser Skript die Art und Weise, wie es aufgerufen wurde. Diese Informationen werden im ersten Befehlszeilenargument gespeichert und mit 0 indiziert. Der folgende Code zeigt, wie Sie den Namen Ihres Python-Skripts erhalten:
import sys
print("The script has the name %s" % (sys.argv[0])
Speichern Sie diesen Code in einer Datei mit dem Namen arguments-program-name.py
, und rufen Sie es dann wie unten gezeigt auf. Die Ausgabe sieht wie folgt aus und enthält den Dateinamen einschließlich des vollständigen Pfads:
$ python arguments-program-name.py
The script has the name arguments-program-name.py
$ python /home/user/arguments-program-name.py
The script has the name /home/user/arguments-program-name.py
Wie Sie dem zweiten Aufruf oben entnehmen können, erhalten wir nicht nur den Namen der Python-Datei, sondern auch den vollständigen Pfad, über den sie aufgerufen wurde.
Zählen der Anzahl der Argumente
In diesem zweiten Beispiel zählen wir einfach die Anzahl der Befehlszeilenargumente mithilfe der integrierten Funktion len()
Methode. sys.argv
ist die Liste, die wir untersuchen müssen. Im folgenden Code ermitteln wir die Anzahl der Argumente und subtrahieren dann 1, da eines dieser Argumente (d. h. das erste) immer als Name der Datei festgelegt ist, was für uns nicht immer nützlich ist. Somit beträgt die tatsächliche Anzahl der vom Benutzer übergebenen Argumente len(sys.argv) - 1
:
import sys
arguments = len(sys.argv) - 1
print ("The script is called with %i arguments" % (arguments))
Speichern Sie diese Datei und nennen Sie sie arguments-count.py. Nachfolgend finden Sie einige Beispiele für den Aufruf dieses Skripts. Dies umfasst drei verschiedene Szenarien:
- Ein Aufruf ohne weitere Kommandozeilenargumente
- Ein Anruf mit zwei Argumenten
- Ein Aufruf mit zwei Argumenten, wobei das zweite eine Zeichenfolge in Anführungszeichen ist, die ein Leerzeichen enthält
$ python arguments-count.py
The script is called with 0 arguments
$ python arguments-count.py --help me
The script is called with 2 arguments
$ python arguments-count.py --option "long string"
The script is called with 2 arguments
Durch Argumente iterieren
Unser drittes Beispiel gibt jedes einzelne an das Python-Skript gesendete Argument aus, mit Ausnahme des Programmnamens selbst. Daher durchlaufen wir die Befehlszeilenargumente beginnend mit dem zweite Listenelement. Denken Sie daran, dass dies Index 1 ist, da Listen in Python auf 0 basieren:
import sys
arguments = len(sys.argv) - 1
position = 1
while (arguments >= position):
print ("Parameter %i: %s" % (position, sys.argv[position]))
position = position + 1
Nachfolgend rufen wir unseren Code auf, der in der Datei arguments-output.py gespeichert wurde. Wie in unserem vorherigen Beispiel veranschaulicht die Ausgabe drei verschiedene Aufrufe:
- Ein Anruf ohne Argumente
- Ein Anruf mit zwei Argumenten
- Ein Aufruf mit zwei Argumenten, wobei das zweite Argument eine Zeichenfolge in Anführungszeichen ist, die ein Leerzeichen enthält
$ python arguments-output.py
$ python arguments-output.py --help me
Parameter 1: --help
Parameter 2: me
$ python arguments-output.py --option "long string"
Parameter 1: --option
Parameter 2: long string
Denken Sie daran, dass es bei der Darstellung des Beispiels für eine Zeichenfolge in Anführungszeichen darum geht, dass Parameter normalerweise durch ein Leerzeichen getrennt werden. es sei denn sie sind von Anführungszeichen umgeben.
Abseilfahnen (absl
)
Die Flags-Bibliothek von Abseil soll Befehlszeilenargumente mit verteilten Befehlszeilenargumenten in die Produktion bringen. Wenn ein Modul Befehlszeilenflags verwendet und in ein anderes Modul importiert wird – das andere Modul importiert auch die Flagsund kann diese verarbeiten, indem er sie an das importierte Modul weiterleitet.
Dadurch werden komplexe Befehlszeilenargumente, die von Modulen gemeinsam genutzt werden, einfacher und weniger ausführlich.
Darüber hinaus können Sie in der Bibliothek die Standardwerte, Beschreibungen und Datentypen der Argumente definieren, sodass keine zusätzlichen Prüfungen und Konvertierungen erforderlich sind.
from absl import flags
import sys
flags.DEFINE_string('name', 'User', 'The name of the user.')
FLAGS = flags.FLAGS
FLAGS(sys.argv)
print(f"Hello {FLAGS.name}!")
Die unterstützten Datentypen sind:
DEFINE_integer()
DEFINE_string()
DEFINE_bool()
DEFINE_enum()
DEFINE_list()
DEFINE_float()
Ebenso gut wie DEFINE_multi_integer()
, DEFINE_multi_string()
und DEFINE_multi_enum()
für die Eingabe mit mehreren Argumenten. Außerdem Laufen --help
, --helpfull
usw. drucken die vorhandenen Flags und ihre Beschreibungen in verschiedenen Formaten.
Sehen Sie sich unseren praxisnahen, praktischen Leitfaden zum Erlernen von Git an, mit Best Practices, branchenweit akzeptierten Standards und einem mitgelieferten Spickzettel. Hören Sie auf, Git-Befehle zu googeln und tatsächlich in Verbindung, um es!
Mit der Bibliothek können Sie auch Validierungen definieren – sowohl in Bezug auf den Bereich, als auch auf ganzzahlige Werte mit einem upper_bound
or lower_bound
Das ist akzeptabel und das Ausführen beliebiger Methoden zur Überprüfung der Werte:
def validate_name(value):
return len(value) > 15
flags.register_validator('name',
validate_name,
message='Name is over 15 characters long.',
flag_values=FLAGS)
Fassen Sie diese in einem konkreten Beispiel zusammen:
from absl import flags
import sys
flags.DEFINE_string('name', 'User', 'The name of the user.')
flags.DEFINE_integer('tasks', 0, 'The number of tasks a user has.', lower_bound=0)
FLAGS = flags.FLAGS
FLAGS(sys.argv)
print(f"{FLAGS.name} has {FLAGS.tasks} tasks to work on.")
$ python flags.py --name=John --tasks=5
John has 5 tasks to work on.
$ python flags.py --name=John --tasks=-1
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_flag.py", line 180, in _parse
return self.parser.parse(argument)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_argument_parser.py", line 168, in parse
raise ValueError('%s is not %s' % (val, self.syntactic_help))
ValueError: -1 is not a non-negative integer
...
Das argparse-Modul
Das argparse-Modul ist seit Python 3.2 verfügbar und eine Erweiterung des optparse
Modul, das bis Python 2.7 existiert. Die Python-Dokumentation enthält eine API-Beschreibung und ein Tutorial, das alle Methoden im Detail behandelt.
Das Modul bietet eine Befehlszeilenschnittstelle mit einer standardisierten Ausgabe, während die beiden erstgenannten Lösungen einen Großteil der Arbeit in Ihren Händen lassen. argparse
ermöglicht die Überprüfung fester und optionaler Argumente, wobei der Name entweder im kurzen oder langen Stil überprüft wird. Als standardmäßiges optionales Argument enthält es -h
, zusammen mit seiner Langversion --help
. Dieses Argument wird von einer Standardhilfemeldung begleitet, die die akzeptierten Argumente beschreibt.
Der folgende Code zeigt die Parser-Initialisierung und die Ausgabe unten zeigt den Basisaufruf, gefolgt von der Hilfemeldung. Im Gegensatz zu den Python-Aufrufen, die wir in den vorherigen Beispielen verwendet haben, denken Sie bei diesen Beispielen daran, Python 3 zu verwenden:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
$ python3 arguments-argparse-basic.py
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]
arguments-argparse-basic.py: error: unrecognized arguments: --verbose
Im nächsten Schritt fügen wir der Hilfenachricht für unsere Benutzer eine benutzerdefinierte Beschreibung hinzu. Die Initialisierung des Parsers auf diese Weise ermöglicht einen zusätzlichen Text. Der folgende Code speichert die Beschreibung im text
Variable, die explizit an die übergeben wird argparse
Klasse als die description
Parameter. Wenn Sie diesen Code unten aufrufen, können Sie sehen, wie die Ausgabe aussieht:
import argparse
text = 'This is a test program. It demonstrates how to use the argparse module with a program description.'
parser = argparse.ArgumentParser(description=text)
parser.parse_args()
$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]
This is a test program. It demonstrates how to use the argparse module with a
program description.
optional arguments:
-h, --help show this help message and exit
Als letzten Schritt fügen wir ein optionales Argument mit dem Namen hinzu -V
, das über ein entsprechendes langes Stilargument mit dem Namen verfügt --version
. Dazu verwenden wir die Methode add_argument()
dass wir mit drei Parametern aufrufen (angezeigt für --version
, nur):
- Der Name des Parameters:
--version
- Der Hilfetext für den Parameter:
help="show program version"
- Aktion (ohne Zusatzwert):
action="store_true"
Der Quellcode dafür wird unten angezeigt. Einlesen der Argumente in die aufgerufene Variable args
erfolgt über die parse_args()
Methode aus dem parser
Objekt. Beachten Sie, dass Sie sowohl die Kurz- als auch die Langversion in einem Anruf einreichen. Abschließend überprüfen Sie, ob die Attribute vorhanden sind args.V
or args.version
werden gesetzt und geben die Versionsmeldung aus:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")
args = parser.parse_args()
if args.version:
print("This is myprogram version 0.1")
$ python3 arguments-argparse-optional.py -V
This is myprogram version 0.1
$ python3 arguments-argparse-optional.py --version
This is myprogram version 0.1
Das --version
Für das Argument muss kein Wert in der Befehlszeile angegeben werden. Deshalb setzen wir das Aktionsargument auf "store_true"
. In anderen Fällen benötigen Sie möglicherweise einen zusätzlichen zugewiesenen Wert, beispielsweise wenn Sie ein bestimmtes Volumen, eine bestimmte Höhe oder Breite angeben. Dies wird im nächsten Beispiel gezeigt. Bitte beachten Sie, dass standardmäßig alle Argumente als Zeichenfolgen interpretiert werden:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--width", "-w", help="set output width")
args = parser.parse_args()
if args.width:
print("Set output width to %s" % args.width)
Hier zeigen wir, was passiert, wenn unterschiedliche Argumentwerte übermittelt werden. Dazu gehören sowohl die Kurz- als auch die Langversion, sowie die Hilfemeldung:
$ python3 arguments-argparse-optional2.py -w 10
Set output width to 10
$ python3 arguments-argparse-optional2.py --width 10
Set output width to 10
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]
optional arguments:
-h, --help show this help message and exit
--width WIDTH, -w WIDTH
set output width
Das getopt-Modul
Wie Sie vielleicht schon bemerkt haben, ist die sys
Das Modul teilt die Befehlszeilenzeichenfolge nur in einzelne Facetten auf. Der Python getopt-Modul geht noch etwas weiter und erweitert die Trennung der Eingabezeichenfolge durch Parametervalidierung. Basierend auf getopt
C-Funktion ermöglicht sowohl kurze als auch lange Optionen, einschließlich einer Wertzuweisung.
In der Praxis erfordert es die sys
Modul, um Eingabedaten ordnungsgemäß zu verarbeiten. Dazu müssen sowohl die sys
Modul und die getopt
Modul müssen vorher geladen werden. Als nächstes entfernen wir aus der Liste der Eingabeparameter das erste Listenelement (siehe Code unten) und speichern die verbleibende Liste der Befehlszeilenargumente in der aufgerufenen Variablen argument_list
:
import getopt, sys
full_cmd_arguments = sys.argv
argument_list = full_cmd_arguments[1:]
print argument_list
Die Argumente in argument_list
kann jetzt mit analysiert werden getopts()
Methode. Aber bevor wir das tun, müssen wir es erzählen getopts()
welche Parameter gültig sind. Sie sind wie folgt definiert:
short_options = "ho:v"
long_options = ["help", "output=", "verbose"]
Dies bedeutet, dass wir diese Argumente zusammen mit einigen zusätzlichen Informationen für gültig halten:
------------------------------------------
long argument short argument with value
------------------------------------------
--help -h no
--output -o yes
--verbose -v no
------------------------------------------
Sie haben vielleicht bemerkt, dass die o
der kurzen Option wurde ein Doppelpunkt vorangestellt, :
. Das sagt getopt
dass dieser Option ein Wert zugewiesen werden soll.
Dies ermöglicht es uns nun, eine Liste von Argumenten zu verarbeiten. Der getopt()
Für die Methode müssen drei Parameter konfiguriert werden – die Liste der tatsächlichen Argumente von argv
sowie die gültigen kurzen und langen Optionen (im vorherigen Codeausschnitt gezeigt).
Der Methodenaufruf selbst wird in einer Try-Catch-Anweisung gespeichert, um Fehler während der Auswertung abzudecken. Eine Ausnahme wird ausgelöst, wenn ein Argument entdeckt wird, das nicht Teil der zuvor definierten Liste ist. Das Python-Skript gibt die Fehlermeldung auf dem Bildschirm aus und wird mit Fehlercode 2 beendet:
try:
arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
print (str(err))
sys.exit(2)
Abschließend werden die Argumente mit den entsprechenden Werten in den beiden genannten Variablen gespeichert arguments
und values
. Jetzt können Sie diese Variablen ganz einfach in Ihrem Code auswerten. Wir können a verwenden for
-loop, um die Liste der erkannten Argumente zu durchlaufen, einen Eintrag nach dem anderen.
for current_argument, current_value in arguments:
if current_argument in ("-v", "--verbose"):
print ("Enabling verbose mode")
elif current_argument in ("-h", "--help"):
print ("Displaying help")
elif current_argument in ("-o", "--output"):
print (("Enabling special output mode (%s)") % (current_value))
Unten sehen Sie die Ausgabe der Ausführung dieses Codes. Wir zeigen, wie das Programm sowohl mit gültigen als auch mit ungültigen Programmargumenten reagiert:
$ python arguments-getopt.py -h
Displaying help
$ python arguments-getopt.py --help
Displaying help
$ python arguments-getopt.py --output=green --help -v
Enabling special output mode (green)
Displaying help
Enabling verbose mode
$ python arguments-getopt.py -verbose
option -e not recognized
Der letzte Aufruf unseres Programms mag zunächst etwas verwirrend wirken. Um es zu verstehen, müssen Sie wissen, dass die Kurzschriftoptionen (manchmal auch Flags genannt) zusammen mit einem einzelnen Bindestrich verwendet werden können. Dadurch kann Ihr Werkzeug viele Optionen einfacher akzeptieren. Zum Beispiel anrufen python arguments-getopt.py -vh
ist das gleiche wie anrufen python arguments-getopt.py -v -h
. Also im letzten Aufruf oben, der getopt
Das Modul ging davon aus, dass der Benutzer versuchen wollte, zu bestehen -e
als Option, was ungültig ist.
Zusammenfassung
In diesem Artikel haben wir viele verschiedene Methoden zum Abrufen von Befehlszeilenargumenten in Python gezeigt, einschließlich der Verwendung sys
, getopt
und argparse
. Die Funktionalität dieser Module variiert, einige bieten viel mehr als andere. sys
ist völlig flexibel, während beide getopt
und argparse
erfordern eine gewisse Struktur. Im Gegensatz dazu decken sie die meisten komplexen Arbeiten ab sys
überlässt es Ihnen. Nachdem Sie die bereitgestellten Beispiele durchgearbeitet haben, sollten Sie feststellen können, welches Modul am besten zu Ihrem Projekt passt.
In diesem Artikel haben wir nicht über andere Lösungen wie die gesprochen docopts
Modul, wir haben es gerade erwähnt. Dieses Modul verfolgt einen völlig anderen Ansatz und wird in einem der nächsten Artikel ausführlich erläutert.