Ich versuche, ein Skript zu schreiben, das mehrere Eingabequellen akzeptiert und mit jeder etwas macht. Etwas wie das
./my_script.py \
-i input1_url input1_name input1_other_var \
-i input2_url input2_name input2_other_var \
-i input3_url input3_name
# notice inputX_other_var is optional
Aber ich kann nicht genau herausfinden, wie das geht argparse
. Es scheint so eingerichtet zu sein, dass jedes Optionsflag nur einmal verwendet werden kann. Ich weiß, wie man einer einzelnen Option ( nargs='*'
oder nargs='+'
) mehrere Argumente zuordnet , aber das lässt mich das -i
Flag trotzdem nicht mehrmals verwenden. Wie mache ich das?
Um ganz klar zu sein, möchte ich am Ende eine Liste von Zeichenfolgenlisten. Damit
[["input1_url", "input1_name", "input1_other"],
["input2_url", "input2_name", "input2_other"],
["input3_url", "input3_name"]]
python
argparse
multiple-arguments
John Allard
quelle
quelle
Antworten:
Hier ist ein Parser, der ein wiederholtes 2 optionales Argument optional behandelt - mit Namen, die definiert sind in
metavar
:parser=argparse.ArgumentParser() parser.add_argument('-i','--input',action='append',nargs=2, metavar=('url','name'),help='help:') In [295]: parser.print_help() usage: ipython2.7 [-h] [-i url name] optional arguments: -h, --help show this help message and exit -i url name, --input url name help: In [296]: parser.parse_args('-i one two -i three four'.split()) Out[296]: Namespace(input=[['one', 'two'], ['three', 'four']])
Dies behandelt den
2 or 3 argument
Fall nicht (obwohl ich vor einiger Zeit einen Patch für einen Python-Fehler geschrieben habe, der einen solchen Bereich behandeln würde).Wie wäre es mit einer separaten Argumentdefinition mit
nargs=3
undmetavar=('url','name','other')
?Das Tupel
metavar
kann auch mitnargs='+'
und verwendet werdennargs='*'
; Die 2 Zeichenfolgen werden als[-u A [B ...]]
oder verwendet[-u [A [B ...]]]
.quelle
Das ist einfach; füge einfach beide
action='append'
undnargs='*'
(oder'+'
) hinzu.import argparse parser = argparse.ArgumentParser() parser.add_argument('-i', action='append', nargs='+') args = parser.parse_args()
Wenn Sie es dann ausführen, erhalten Sie
In [32]: run test.py -i input1_url input1_name input1_other_var -i input2_url i ...: nput2_name input2_other_var -i input3_url input3_name In [33]: args.i Out[33]: [['input1_url', 'input1_name', 'input1_other_var'], ['input2_url', 'input2_name', 'input2_other_var'], ['input3_url', 'input3_name']]
quelle
-i
sollte so konfiguriert sein, dass 3 Argumente akzeptiert und dieappend
Aktion verwendet werden.>>> p = argparse.ArgumentParser() >>> p.add_argument("-i", nargs=3, action='append') _AppendAction(...) >>> p.parse_args("-i a b c -i d e f -i g h i".split()) Namespace(i=[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']])
Um einen optionalen Wert zu verarbeiten, können Sie versuchen, einen einfachen benutzerdefinierten Typ zu verwenden. In diesem Fall ist das Argument to
-i
eine einzelne durch Kommas getrennte Zeichenfolge, wobei die Anzahl der Teilungen auf 2 begrenzt ist. Sie müssten die Werte nachbearbeiten, um sicherzustellen, dass mindestens zwei Werte angegeben sind.>>> p.add_argument("-i", type=lambda x: x.split(",", 2), action='append') >>> print p.parse_args("-i a,b,c -i d,e -i g,h,i,j".split()) Namespace(i=[['a', 'b', 'c'], ['d', 'e'], ['g', 'h', 'i,j']])
Definieren Sie für mehr Kontrolle eine benutzerdefinierte Aktion. Dieser erweitert die integrierte
_AppendAction
(vonaction='append'
) verwendete Funktion, überprüft jedoch nur den Bereich, in dem die Anzahl der Argumente angegeben ist-i
.class TwoOrThree(argparse._AppendAction): def __call__(self, parser, namespace, values, option_string=None): if not (2 <= len(values) <= 3): raise argparse.ArgumentError(self, "%s takes 2 or 3 values, %d given" % (option_string, len(values))) super(TwoOrThree, self).__call__(parser, namespace, values, option_string) p.add_argument("-i", nargs='+', action=TwoOrThree)
quelle
inputX_other_var
das optional ist.