2010-01-18 6 views
17

Ich verwende getopt, um ein optionales Befehlszeilenargument zu verarbeiten, das eine Liste akzeptieren sollte. Etwas wie folgt aus:Angeben einer Liste als ein Befehlszeilenargument in Python

foo.py --my_list=[1, 2, 3, 4,5] 

Aber diese trimmt alles nach "[1"

Meine Fragen sind: A) Gibt es eine Möglichkeit, eine Liste zu spezifizieren, ohne es in einen String zu konvertieren? (mit getopt)

B) Wenn ich die Liste in eine Zeichenfolge konvertieren soll, wie diese Liste in eine Zeichenfolge konvertieren? z.B. etwas wie mylist.split ("?"), um eckige Klammern loszuwerden ?? Gibt es einen besseren Weg?

Vielen Dank

Antwort

23

Es gibt zwei Optionen, die ich mir vorstellen kann:

  • Verwenden optparse, und verwenden Sie append Aktion angeben, was Sie tun: foo.py --my_list=1 --my_list=2 ....
  • Geben Sie Ihre Befehlszeile als foo.py --my_list='1,2,3,4,5' an, und verwenden Sie dann x.split(','), um Ihre Werte in einer Liste abzurufen. Sie können getopt oder optparse für diese Methode verwenden.

Der Vorteil des ersten Verfahrens ist, dass Sie ganzzahlige Werte in der Liste direkt zu bekommen, auf Kosten von der Kommandozeile länger ist (aber Sie können eine Einzel charecter Option für --my_list hinzufügen, wenn Sie möchten). Der Vorteil der zweiten ist die kürzere Befehlszeile, aber nach der split() müssen Sie die Zeichenfolgenwerte '1', '2' usw. in Ganzzahlen konvertieren (ziemlich einfach).

+2

Da dieser Beitrag 5 Jahre alt ist, ist 'optparse' jetzt veraltet für' argparse' – SAAD

+0

Was meinen Sie mit 'append action'? Es klingt aufregend, aber nicht sicher, wovon du sprichst. –

+0

@MonicaHeddneck Siehe https://docs.python.org/3/library/optparse.html#standard-option-actions - sie haben ein Beispiel für die Aktion "append": 'parser.add_option (" - t "," --tracks ", action =" append ", type =" int ")'. –

7

Vielleicht sollten Sie das Argument einfach in Anführungszeichen einschließen?

foo.py "--my_list=[1, 2, 3, 4,5]" 

Andernfalls wird jeder Speicherplatz als Trennzeichen für Argumente behandelt.

+2

Und das ist nicht wegen der Python aber aufgrund der Schale, die die Argumente und stellt sie dem Python-Programm analysiert. – extraneon

+1

Teilweise wahr. Unter Windows ist die Befehlszeile nur eine Zeichenfolge. Und selbst UNIX hat keine spezielle Datenstruktur, die Argumente an das Programm übergibt, es ist immer noch nur eine Zeichenkette. Es ist jedoch eine weit verbreitete Konvention, aber nicht universell. Und ja, die C-Laufzeit hat dafür Spezifikationen. – Joey

+1

Sie können auch '--my-list =" [1, 2, 3, 4,5] "' eingeben. Normalerweise benutze ich dieses Formular, weil es normalerweise etwas wie '--my-list =" $ MY_LIST "' ist. –

1

Von der Python optparse Hilfeseite: "

parser.add_option("-f") 
parser.add_option("-p", type="float", nargs=3, dest="point") 

Da es den Zeilenbefehl parst

-f foo.txt -p 1 -3.5 4 -fbar.txt 

optparse

options.f = "foo.txt" 
options.point = (1.0, -3.5, 4.0) 
options.f = "bar.txt" 

gesetzt wird"

10

Wenn ich nicht einen Standard-Parser (optparse oder argparse) auf meine Bewerbung dann verwende ich die ast.literal_eval Funktionseingabe verwenden können Argumente des Typs Liste zu analysieren, wie folgt:

import sys, ast 

inputList = ast.literal_eval(sys.argv[1]) 
print type(inputList) 
print inputList 

Lassen Sie vermuten, dass dieser Code gespeichert ist, in der Datei testParser.py.Durch die Ausführung des Skripts:

$ python testParser.py "[1,2,3,4, [123, 456, 789], 'asdasd']" 

wir folgende Ausgabe:

<type 'list'> 
[1, 2, 3, 4, [123, 456, 789], 'asdasd'] 

Also, mit der sicher genug ast.literal_eval Funktion und Einfügen der Liste als eine Reihe von Code haben wir das gewünschte Ergebnis.

Nützliche Links:

Using python's eval() vs. ast.literal_eval()?

http://docs.python.org/2/library/functions.html?highlight=eval#eval

1

Ein aktualisierte Weg ist, die argparse Bibliothek zu verwenden und die Liste als Befehlszeilenargument hinzufügen. Auf diese Weise müssen Sie kein manuelles Parsing durchführen.

Beispiel:

parser = argparse.ArgumentParser() 
parser.add_argument(
     "-values", 
     nargs="*", # expects ≥ 0 arguments 
     type=int, 
     default=[35, 40, 50, 60, 70, 80, 90], # default list if no arg value 
    ) 

Was du dann so nennen würde:

python3 someprogram.py -values 1 2 3 
Verwandte Themen