2016-04-04 9 views
0

Ich bin ein Python-Skript erstellen, die die Argumente vom Benutzer angegebenen verwendet eine ausführbare Datei zu starten:subprocess.Popen optionale Argumente

parser = argparse.ArgumentParser() 
parser.add_argument('-c', '--stringC', dest="stringC", help="stringC", type=str) 
parser.add_argument('-f', '--stringF', dest="stringF", help="stringF", type=str) 
parser.add_argument('-o', '--stringO', dest="stringO", help="stringO", type=str) 
parser.add_argument('-d', '--stringD', dest="stringD", help="stringD", type=str) 
parser.add_argument('-s', '--stringS', dest="stringS", help="stringS", type=str) 
args = parser.parse_args() 

command = 'executable-location' 
statement = [command, '-c', stringC, '-f', stringF, '-o', stringO, '-d', stringD, '-s', stringS] 
p = subprocess.Popen(statement) 

Das Problem ist, dass einige dieser Parameter für die ausführbare Datei optional sind und wenn Wenn nicht angegeben, verwendet das Programm eigene Standardwerte. Daher werden derzeit alle Parameter verwendet, obwohl ich manchmal die Standardwerte verwenden möchte.

Idealerweise möchte ich der ausführbaren Datei nur Argumente geben, die analysiert wurden. Ich habe versucht,

statement = [command, args] 
p = subprocess.Popen(statement2) 

und

p = subprocess.Popen(args) 

aber es gibt mir die folgende Fehlermeldung:

TypeError: 'Namespace' object is not iterable

Hoffentlich jemand mir dabei helfen kann. Danke im Voraus.

Antwort

0

Die einfachste Lösung, falls möglich, besteht darin, die Programmstandards in Ihren Parser zu integrieren.

# For example 
parser.add_argument('-f', '--stringF', dest="stringF", 
        help="stringF", type=str, 
        default="-f's default) 

Dann müssen Sie sich keine Sorgen darüber, ob oder nicht args.stringF in der Argumentliste zu verwenden.

Andernfalls müssen Sie die Befehlsliste eine Option zu einer Zeit erstellen.

statement = [command] 
if args.stringF is not None: 
    statement += ["-f", args.StringF] 
# etc 
+0

Vielen Dank, ich entschied mich für die zweite Option, da ich das Skript nicht jedes Mal aktualisieren möchte, wenn sich die Standardwerte des Programms ändern. – Aelion

0

Ich bin nicht ganz sicher, was Sie versuchen zu tun, sondern kann dies helfen:

einen Parser definieren, mit 2 verschiedenen Arten von Standardwerten:

>>> import argparse 
>>> parser=argparse.ArgumentParser() 
>>> parser.add_argument('-f','--foo',default='FOO') 
>>> parser.add_argument('-b','--bar',default=argparse.SUPPRESS) 

Analysieren Sie einen Fall ohne Argumente. Beachten Sie, dass der resultierende Namespace einen Wert für foo (der die Standardeinstellung ist), aber keine für bar - das ist wegen der SUPPRESS Standard.

>>> args=parser.parse_args([]) 
>>> print(args) 
Namespace(foo='FOO') 

args.foo wird die Zeichenfolge 'FOO' geben. Sie können aber auch den Namespace zu einem Wörterbuch konvertieren, oder auf eine Liste von Tupeln

>>> print(vars(args)) 
{'foo': 'FOO'} 
>>> print(vars(args).items()) 
[('foo', 'FOO')] 

Wenn ich ein paar Argumente, die args Namespace geben, wie hat:

>>> args=parser.parse_args(['-f','val1','-b','val2']) 
>>> print(args) 
Namespace(bar='val2', foo='val1') 

und die gleiche Wörterbuch und Liste Konvertierung ist möglich.

>>> print(vars(args).items()) 
[('foo', 'val1'), ('bar', 'val2')] 

Sie haben die Wahl, ob die args einen angemessenen Standard enthält, oder keinen Wert überhaupt für Argumente, dass der Benutzer nicht geben. Der Standardwert default ist None, für den auch leicht zu testen ist (z. B. args.baz is None).

Constructing eine einfache Liste wie

['command', 'foo', 'val1', 'bar', 'val2'] 

sollte einfach sein. Mit -f und -b anstelle der Standard-dest Namen werden ein bisschen mehr fiedeln.

Verwandte Themen