2014-11-28 17 views
26

ich ein solches Skript:Wie Argumente iterieren

import argparse 

parser = argparse.ArgumentParser(
       description='Text file conversion.' 
       ) 
parser.add_argument("inputfile", help="file to process", type=str) 
parser.add_argument("-o", "--out", default="output.txt", 
        help="output name") 
parser.add_argument("-t", "--type", default="detailed", 
        help="Type of processing") 

args = parser.parse_args() 

for arg in args: 
    print(arg) 

Aber es funktioniert nicht. Ich erhalte Fehler:

TypeError: 'Namespace' object is not iterable 

Wie man über Argumente und ihren Wert iteriert?

Antwort

39

Bitte addieren Sie 'vars', wenn Sie wollen Iterierte über Namespace-Objekt:

for arg in vars(args): 
    print arg, getattr(args, arg) 
13

Namespace Objekte sind nicht durchsuchbar, die Standard-docs folgenden empfehlen zu tun, wenn Sie einen Wörterbuch wollen:

>>> vars(args) 
{'foo': 'BAR'} 

So

for key,value in vars(args).iteritems(): 
    # do stuff 

Um ehrlich zu sein, ich bin nicht sicher, warum Sie wollen um über die Argumente zu iterieren. Das verhindert den Zweck, einen Argumentparser zu haben.

+0

eine typische Verwendung hierfür ist die Implementierung eines 'debug-input'-Modus, bei dem ein Skript alle Eingabeargumente ausgibt und beendet; nützlich für Dinge wie sicherzustellen, dass die Datetime-Eingabewerte richtig interpretiert wurden –

0

ArgumentParser.parse_args gibt ein Namespace Objekt anstelle eines iterable Arrays.

Zu Ihrer Information https://docs.python.org/3/library/argparse.html#parsing-arguments

ArgumentParser parses arguments through the parse_args() method. This will inspect the command line, convert each argument to the appropriate type and then invoke the appropriate action. 

Und es soll nicht so verwendet werden. Betrachten Sie Ihren Anwendungsfall, in dem Dokument heißt es argparse wird herausfinden, wie diese aus sys.argv zu analysieren., was bedeutet, dass Sie nicht über diese Argumente iterieren müssen.

6

Nach

args = parser.parse_args() 

die Argumente aufzurufen, zu verwenden:

print args # or print(args) in python3 

Die args Objekt (vom Typ argparse.Namespace) nicht iterable (dh keine Liste), aber es hat eine .__str__ Methode, die die Werte schön anzeigt.

args.out und args.type geben Sie die Werte der 2 Argumente, die Sie definiert haben. Dies funktioniert die meiste Zeit. getattr(args, key) die allgemeinste Art des Zugriffs auf die Werte, wird aber normalerweise nicht benötigt.

vars(args) 

verwandelt den Namespace in ein Wörterbuch, auf das Sie mit allen Wörterbuchmethoden zugreifen können. Dies ist in der dargelegt.

ref: die Namespace Absatz der docs - https://docs.python.org/2/library/argparse.html#the-namespace-object

+0

Danke für das nette Schreiben! – Hua2308

1

Ich args.__dict__ verwenden, die Sie Struktur Zugriff auf die zugrunde liegenden dict lässt. Dann, es ist eine einfache Schlüssel-Wert-Iteration:

for k in args.__dict__: 
    print k, args.__dict__[k] 
1

die _actions von Ihrem Parser Parsing scheint wie eine anständige Vorstellung. Anstatt parse_args() auszuführen und dann zu versuchen, Dinge aus deinem Namespace herauszuholen.

import argparse 

parser = argparse.ArgumentParser(
       description='Text file conversion.') 
parser.add_argument("inputfile", help="file to process", type=str) 
parser.add_argument("-o", "--out", default="output.txt", 
       help="output name") 
parser.add_argument("-t", "--type", default="detailed", 
       help="Type of processing") 
options = parser._actions 
for k in options: 
    print(getattr(k, 'dest'), getattr(k, 'default')) 

Sie können den ‚dest‘ Teil ändern ‚Auswahl‘ zum Beispiel, wenn Sie die voreingestellten Standardwerte für einen Parameter in einem anderen Skript müssen (durch die Optionen in einer Funktion zum Beispiel zurückkehrt).