In diesem Tutorial lernst du, wie du ein oder mehrere Argumente aus der Kommandozeile bzw. dem Terminal mit den Modulen getopt, sys und argparse verarbeitest.
Wenn du ein Data-Science- oder Machine-Learning-Projekt planst, ist es ganz normal, die Entwicklung in einem Jupyter Notebook zu starten. Es bietet Interaktivität, lässt dich Module schnell ausführen und vieles mehr. Es gibt viele gute Gründe, Jupyter Notebooks als bevorzugtes Arbeitswerkzeug zu wählen – gerade für Data-Science- oder Machine-Learning-Projekte. Darum soll es in diesem Tutorial jedoch nicht gehen.
Stell dir vor, du musst ein Python-Skript als Batchjob ausführen, um Daten in deinem Data-Science-Projekt zu laden. Oder du willst ein Machine-Learning-Modell per Python-Skript auf einen Remote-Server deployen. In solchen Fällen reicht ein einfaches python your_script.py oft nicht aus. Du musst zusätzliche Optionen oder Argumente zusammen mit python your_script.py übergeben. Vielleicht kennst du das bereits vom Ausführen von Befehlen (wie ps, ls usw.) im Linux-Terminal.
In diesem Tutorial lernst du, wie du zusätzliche Argumente und Optionen aus der Kommandozeile ausliest, die zusammen mit einem Python-Skript übergeben werden. Hier ist die heutige Agenda:
Eine kurze Einführung ins Argumentparsen
Argumentparsen in Python
Mit sys.argv
Mit getopt
Mit argparse
Hinweis: Dieses Tutorial setzt grundlegende Python-Kenntnisse voraus.
Was ist Argumentparsen?
Wenn du Linux nutzt, kennst du das vermutlich schon. Um eine Übersicht der Dateien und Ordner in einem Verzeichnis zu erhalten, verwendet man häufig den Befehl ls. Eine typische Ausgabe von ls sieht so aus:
Du kannst dem Befehl ls allerdings viele Optionen mitgeben, zum Beispiel -l. So sieht die Ausgabe dann aus:
Mit der Option -l bekommst du zusätzliche Informationen. In diesem Zusammenhang gibt es einen kleinen Unterschied zwischen einer Option und einem Argument. Um eine Datei oder einen Ordner im aktuellen Verzeichnis zu löschen, nutzt man häufig den Befehl rm. Angenommen, du hast eine Textdatei namens demo.txt und führst rm demo.txt aus, um sie zu löschen. In diesem Fall ist demo.txt das Argument, das du dem Befehl rm übergibst. Wenn du kein Argument an rm übergibst, erhältst du eine Fehlermeldung wie diese:
Was ist also der Unterschied zwischen einer Option und einem Argument? Ziemlich offensichtlich: Optionen sind optional, Argumente sind (oft) notwendig. Für ls musst du nichts übergeben, damit es etwas ausgibt.
Wenn du ls -l oder rm demo.txt eingibst, wird der Befehl vom Betriebssystem nach bestimmten Regeln „geparst“. Dieser Mechanismus ist in der Regel von den Entwicklerinnen und Entwicklern des Betriebssystems vorgegeben und wird als Parsing bezeichnet.
Wenn du mehr zu Linux-Befehlen sowie deren Optionen und Argumenten lernen möchtest, ist das Buch Unix Concepts and Applications sehr zu empfehlen.
So viel zur Einführung ins Argumentparsen. Fast alle Programmiersprachen unterstützen das Parsen von Argumenten – Python natürlich auch. Es gibt drei weit verbreitete Wege, Argumente in Python zu parsen:
sys.argv
getopt
argparse
Schauen wir uns die drei Varianten der Reihe nach an.
Argumentparsen mit sys.argv
Starten wir einfach. Im ersten Beispiel legst du eine Python-Datei namens demo1.py an. Dein Programm akzeptiert eine beliebige Anzahl von Argumenten, die beim Starten über die Kommandozeile (oder das Terminal) übergeben werden. Es gibt anschließend die übergebenen Argumente sowie deren Gesamtzahl aus.
Wenn du zum Beispiel python demo1.py abc 123 ausführst, erhältst du:
Number ofarguments:3Argument(s) passed:['demo1.py','abc','123']Bereitgestellt von
Beachte: Das erste Argument ist immer der Dateiname des Python-Skripts. Der Code lässt sich aber so anpassen, dass dieser Eintrag nicht berücksichtigt wird.
Hier ist der Code:
import sys
print('Number of arguments: {}'.format(len(sys.argv)))print('Argument(s) passed: {}'.format(str(sys.argv)))Bereitgestellt von
Zuerst importierst du das Python-Modul sys, das zur Standardinstallation gehört. Danach nutzt du argv, eine Liste mit allen Argumenten, die an ein Python-Skript übergeben wurden, wobei argv[0] den Skriptnamen enthält. Wenn du sys.argv in einer Codezelle wie unten ausführst, erhältst du eine Liste von Konfigurationsdateien, die den IPython-Kernel am Laufen halten. Daran solltest du besser nichts ändern.
['/home/nbuser/anaconda3_501/lib/python3.6/site-packages/ipykernel/__main__.py','-f','/home/nbuser/.local/share/jupyter/runtime/kernel-dabba4f7-e3e0-4c39-99d2-261ba835c53f.json']Bereitgestellt von
Als Nächstes schauen wir uns an, wie du das Modul getopt zum Parsen von Argumenten (und Optionen) verwendest.
Argumentparsen mit getopt
Im Vergleich zu sys.argv bietet das Modul getopt deutlich mehr Flexibilität. Skizzieren wir zunächst ein Beispiel und schreiben dann den passenden Code.
Angenommen, du hast ein Python-Skript veröffentlicht, aber noch nicht dokumentiert. Du möchtest Nutzenden dennoch hilfreiches Feedback geben, wenn sie das Skript falsch ausführen. Dein Skript addiert zwei Zahlen und gibt das Ergebnis aus. Die einzige Bedingung: Die Eingaben werden als Kommandozeilenargumente zusammen mit dem Skript übergeben.
Praktisch sollte das Skript idealerweise so ausgeführt werden:
python add_numbers.py -a 3 -b 8
Die Ausgabe soll 11 sein. Hier sind -a und -b die Optionen, 3 und 8 die zugehörigen Argumente. Optionen verbessern nicht nur die Lesbarkeit, sondern steuern auch den Ablauf der Auswertung (denk daran, wenn statt Addition beispielsweise eine Division erfolgen soll). Schauen wir uns den Code an:
import getopt
import sys
# Get the arguments from the command-line except the filename
argv = sys.argv[1:]sum=0try:# Define the getopt parameters
opts, args = getopt.getopt(argv,'a:b:',['foperand','soperand'])# Check if the options' length is 2 (can be enhanced)iflen(opts)==0andlen(opts)>2:print('usage: add.py -a <first_operand> -b <second_operand>')else:# Iterate the options and get the corresponding valuesfor opt, arg in opts:sum+=int(arg)print('Sum is {}'.format(sum))except getopt.GetoptError:# Print something usefulprint('usage: add.py -a <first_operand> -b <second_operand>')
sys.exit(2)Bereitgestellt von
Die Idee ist, zunächst alle Argumente mit sys.argv einzulesen und sie anschließend zu verarbeiten. Der wichtigste Codeabschnitt ist: opts, args = getopt.getopt(argv, 'a:b:', ['foperand', 'soperand'])
Die Signatur der Methode getopt() lautet:
getopt.getopt(args, shortopts, longopts=[])
args ist die Liste der aus der Kommandozeile übernommenen Argumente.
shortopts ist die Stelle, an der du die Optionsbuchstaben angibst. Wenn du a: angibst, bedeutet das, dass zu deiner Option a ein Wert als Argument übergeben werden muss. Technisch kannst du hier beliebig viele Optionen definieren. Beim Aufruf in der Kommandozeile müssen diese Optionen mit „-“ beginnen.
longopts enthält die Langformen der shortopts. Sie beginnen mit „--“.
Du hast shortopts als a:b: definiert. Dein Python-Skript erwartet also zwei Optionen mit den Buchstaben „a“ und „b“. Durch den Doppelpunkt gibst du an, dass diesen Optionen jeweils ein Argument folgt.
Die longopts hast du als ['foperand', 'soperand'] definiert. Damit akzeptiert dein Code f_operand und s_operand als Alternativen zu a und b – jeweils mit vorangestelltem --.
Das Modul getopt stellt mit GetoptError außerdem eine praktische Exception-Klasse bereit, um hilfreiche Meldungen auszugeben und die Nutzenden bei der richtigen Verwendung deines Skripts zu unterstützen. Deshalb ist der funktionale Teil in einen try-Block eingebettet und der except-Block entsprechend definiert.
So führst du das Python-Skript aus:
Hinweis: Das obige Skript ist nicht darauf ausgelegt, die longopts zu behandeln. Das kannst du als Übung ergänzen.
Als Nächstes sehen wir uns argparse für das Argumentparsen an.
Argumentparsen mit argparse
Wie du gesehen hast, sind die ersten beiden Varianten nicht besonders lesbar. Mit argparse wirst du außerdem feststellen, dass ihnen auch an Flexibilität einiges fehlt. Um die Nutzung von argparse zu verstehen, starten wir mit einem Codesnippet, das das obige Szenario umsetzt.
import argparse
# Construct the argument parser
ap = argparse.ArgumentParser()# Add the arguments to the parser
ap.add_argument("-a","--foperand", required=True,help="first operand")
ap.add_argument("-b","--soperand", required=True,help="second operand")
args =vars(ap.parse_args())# Calculate the sumprint("Sum is {}".format(int(args['foperand'])+int(args['soperand'])))Bereitgestellt von
Erstmal Grundsätzliches: argparse gehört – wie die anderen beiden Module – zur Standardinstallation von Python. Du erzeugst zunächst ein argparse-Objekt. Der Rest wird dann sehr viel einfacher. Betrachte zum Beispiel diese Zeile:
Hier definierst du ein Argument, das beim Ausführen des Skripts übergeben werden soll. Du gibst die Kurzform per Buchstabe und die Langform an. Mit required=True verlangst du die Angabe explizit. Über help lieferst du eine verständliche Beschreibung, die angezeigt wird, wenn das Skript nicht korrekt aufgerufen wird.
Für das zweite Argument gilt dasselbe. Du greifst auf die übergebenen Werte über ihre jeweiligen Schlüssel zu.
Das Snippet zeigt klar, wie einfach und flexibel sich Aufgaben zum Kommandozeilen-Argumentparsen mit argparse lösen lassen. So kannst du mit dem Skript arbeiten:
Du siehst: Mit argparse wird der gesamte Prozess deutlich komfortabler.
Wie geht es weiter?
Danke, dass du bis zum Ende dabeigeblieben bist. Jetzt kennst du die nativen Python-Module, mit denen du Argumente verarbeiten kannst, die zusammen mit deinem Skript aus der Kommandozeile übergeben werden. Als Übung kannst du deine Machine-Learning- und Data-Science-Projekte so anpassen, dass sie Argumente parsen und sich als praktische Skript-Tools nutzen lassen. Natürlich nicht nur für ML oder Data Science, sondern überall dort, wo es passt. Das war’s für heute. Wenn du deine Python-Kompetenzen weiter ausbauen möchtest, schau dir den DataCamp-Kurs Python Data Science Toolbox (Part 1) an.
Lerne die Funktionen und Methoden von Python-Listen kennen. Schau dir jetzt die Code-Beispiele für list() und andere Python-Funktionen und -Methoden an!
Wenn du ein Data-Science- oder Machine-Learning-Projekt planst, ist es ganz normal, die Entwicklung in einem Jupyter Notebook zu starten. Es bietet Interaktivität, lässt dich Module schnell ausführen und vieles mehr. Es gibt viele gute Gründe, Jupyter Notebooks als bevorzugtes Arbeitswerkzeug zu wählen – gerade für Data-Science- oder Machine-Learning-Projekte. Darum soll es in diesem Tutorial jedoch nicht gehen.
Stell dir vor, du musst ein Python-Skript als Batchjob ausführen, um Daten in deinem Data-Science-Projekt zu laden. Oder du willst ein Machine-Learning-Modell per Python-Skript auf einen Remote-Server deployen. In solchen Fällen reicht ein einfaches
python your_script.pyoft nicht aus. Du musst zusätzliche Optionen oder Argumente zusammen mitpython your_script.pyübergeben. Vielleicht kennst du das bereits vom Ausführen von Befehlen (wieps,lsusw.) im Linux-Terminal.In diesem Tutorial lernst du, wie du zusätzliche Argumente und Optionen aus der Kommandozeile ausliest, die zusammen mit einem Python-Skript übergeben werden. Hier ist die heutige Agenda:
sys.argvgetoptargparseHinweis: Dieses Tutorial setzt grundlegende Python-Kenntnisse voraus.
Was ist Argumentparsen?
Wenn du Linux nutzt, kennst du das vermutlich schon. Um eine Übersicht der Dateien und Ordner in einem Verzeichnis zu erhalten, verwendet man häufig den Befehl
ls. Eine typische Ausgabe vonlssieht so aus:Du kannst dem Befehl
lsallerdings viele Optionen mitgeben, zum Beispiel-l. So sieht die Ausgabe dann aus:Mit der Option
-lbekommst du zusätzliche Informationen. In diesem Zusammenhang gibt es einen kleinen Unterschied zwischen einer Option und einem Argument. Um eine Datei oder einen Ordner im aktuellen Verzeichnis zu löschen, nutzt man häufig den Befehlrm. Angenommen, du hast eine Textdatei namensdemo.txtund führstrm demo.txtaus, um sie zu löschen. In diesem Fall istdemo.txtdas Argument, das du dem Befehlrmübergibst. Wenn du kein Argument anrmübergibst, erhältst du eine Fehlermeldung wie diese:Was ist also der Unterschied zwischen einer Option und einem Argument? Ziemlich offensichtlich: Optionen sind optional, Argumente sind (oft) notwendig. Für
lsmusst du nichts übergeben, damit es etwas ausgibt.Wenn du
ls -loderrm demo.txteingibst, wird der Befehl vom Betriebssystem nach bestimmten Regeln „geparst“. Dieser Mechanismus ist in der Regel von den Entwicklerinnen und Entwicklern des Betriebssystems vorgegeben und wird als Parsing bezeichnet.Wenn du mehr zu Linux-Befehlen sowie deren Optionen und Argumenten lernen möchtest, ist das Buch Unix Concepts and Applications sehr zu empfehlen.
So viel zur Einführung ins Argumentparsen. Fast alle Programmiersprachen unterstützen das Parsen von Argumenten – Python natürlich auch. Es gibt drei weit verbreitete Wege, Argumente in Python zu parsen:
Schauen wir uns die drei Varianten der Reihe nach an.
Argumentparsen mit sys.argv
Starten wir einfach. Im ersten Beispiel legst du eine Python-Datei namens
demo1.pyan. Dein Programm akzeptiert eine beliebige Anzahl von Argumenten, die beim Starten über die Kommandozeile (oder das Terminal) übergeben werden. Es gibt anschließend die übergebenen Argumente sowie deren Gesamtzahl aus.Wenn du zum Beispiel
python demo1.py abc 123ausführst, erhältst du:Beachte: Das erste Argument ist immer der Dateiname des Python-Skripts. Der Code lässt sich aber so anpassen, dass dieser Eintrag nicht berücksichtigt wird.
Hier ist der Code:
Zuerst importierst du das Python-Modul
sys, das zur Standardinstallation gehört. Danach nutzt duargv, eine Liste mit allen Argumenten, die an ein Python-Skript übergeben wurden, wobeiargv[0]den Skriptnamen enthält. Wenn dusys.argvin einer Codezelle wie unten ausführst, erhältst du eine Liste von Konfigurationsdateien, die den IPython-Kernel am Laufen halten. Daran solltest du besser nichts ändern.Als Nächstes schauen wir uns an, wie du das Modul
getoptzum Parsen von Argumenten (und Optionen) verwendest.Argumentparsen mit getopt
Im Vergleich zu
sys.argvbietet das Modulgetoptdeutlich mehr Flexibilität. Skizzieren wir zunächst ein Beispiel und schreiben dann den passenden Code.Angenommen, du hast ein Python-Skript veröffentlicht, aber noch nicht dokumentiert. Du möchtest Nutzenden dennoch hilfreiches Feedback geben, wenn sie das Skript falsch ausführen. Dein Skript addiert zwei Zahlen und gibt das Ergebnis aus. Die einzige Bedingung: Die Eingaben werden als Kommandozeilenargumente zusammen mit dem Skript übergeben.
Praktisch sollte das Skript idealerweise so ausgeführt werden:
python add_numbers.py -a 3 -b 8Die Ausgabe soll 11 sein. Hier sind
-aund-bdie Optionen, 3 und 8 die zugehörigen Argumente. Optionen verbessern nicht nur die Lesbarkeit, sondern steuern auch den Ablauf der Auswertung (denk daran, wenn statt Addition beispielsweise eine Division erfolgen soll). Schauen wir uns den Code an:Die Idee ist, zunächst alle Argumente mit
sys.argveinzulesen und sie anschließend zu verarbeiten. Der wichtigste Codeabschnitt ist:opts, args = getopt.getopt(argv, 'a:b:', ['foperand', 'soperand'])Die Signatur der Methode
getopt()lautet:getopt.getopt(args, shortopts, longopts=[])argsist die Liste der aus der Kommandozeile übernommenen Argumente.shortoptsist die Stelle, an der du die Optionsbuchstaben angibst. Wenn dua:angibst, bedeutet das, dass zu deiner Optionaein Wert als Argument übergeben werden muss. Technisch kannst du hier beliebig viele Optionen definieren. Beim Aufruf in der Kommandozeile müssen diese Optionen mit „-“ beginnen.longoptsenthält die Langformen dershortopts. Sie beginnen mit „--“.Du hast
shortoptsalsa:b:definiert. Dein Python-Skript erwartet also zwei Optionen mit den Buchstaben „a“ und „b“. Durch den Doppelpunkt gibst du an, dass diesen Optionen jeweils ein Argument folgt.Die
longoptshast du als['foperand', 'soperand']definiert. Damit akzeptiert dein Codef_operandunds_operandals Alternativen zuaundb– jeweils mit vorangestelltem--.Das Modul
getoptstellt mitGetoptErroraußerdem eine praktische Exception-Klasse bereit, um hilfreiche Meldungen auszugeben und die Nutzenden bei der richtigen Verwendung deines Skripts zu unterstützen. Deshalb ist der funktionale Teil in einentry-Block eingebettet und derexcept-Block entsprechend definiert.So führst du das Python-Skript aus:
Hinweis: Das obige Skript ist nicht darauf ausgelegt, die
longoptszu behandeln. Das kannst du als Übung ergänzen.Als Nächstes sehen wir uns
argparsefür das Argumentparsen an.Argumentparsen mit argparse
Wie du gesehen hast, sind die ersten beiden Varianten nicht besonders lesbar. Mit
argparsewirst du außerdem feststellen, dass ihnen auch an Flexibilität einiges fehlt. Um die Nutzung vonargparsezu verstehen, starten wir mit einem Codesnippet, das das obige Szenario umsetzt.Erstmal Grundsätzliches:
argparsegehört – wie die anderen beiden Module – zur Standardinstallation von Python. Du erzeugst zunächst einargparse-Objekt. Der Rest wird dann sehr viel einfacher. Betrachte zum Beispiel diese Zeile:ap.add_argument("-a", "--foperand", required=True, help="first operand")Hier definierst du ein Argument, das beim Ausführen des Skripts übergeben werden soll. Du gibst die Kurzform per Buchstabe und die Langform an. Mit
required=Trueverlangst du die Angabe explizit. Überhelplieferst du eine verständliche Beschreibung, die angezeigt wird, wenn das Skript nicht korrekt aufgerufen wird.Für das zweite Argument gilt dasselbe. Du greifst auf die übergebenen Werte über ihre jeweiligen Schlüssel zu.
Das Snippet zeigt klar, wie einfach und flexibel sich Aufgaben zum Kommandozeilen-Argumentparsen mit
argparselösen lassen. So kannst du mit dem Skript arbeiten:Du siehst: Mit
argparsewird der gesamte Prozess deutlich komfortabler.Wie geht es weiter?
Danke, dass du bis zum Ende dabeigeblieben bist. Jetzt kennst du die nativen Python-Module, mit denen du Argumente verarbeiten kannst, die zusammen mit deinem Skript aus der Kommandozeile übergeben werden. Als Übung kannst du deine Machine-Learning- und Data-Science-Projekte so anpassen, dass sie Argumente parsen und sich als praktische Skript-Tools nutzen lassen. Natürlich nicht nur für ML oder Data Science, sondern überall dort, wo es passt. Das war’s für heute. Wenn du deine Python-Kompetenzen weiter ausbauen möchtest, schau dir den DataCamp-Kurs Python Data Science Toolbox (Part 1) an.