2016-05-05 5 views
0

Ich arbeite an einem einfachen Git/Redmine Leim Skript, aber ich habe einige Schwierigkeiten mit optionalen Argumenten mit dem Python argparse Modul.Wie mache ich ein argparse-Argument optional, wenn Subparser verwendet werden?

Mit dem folgenden Code:

import argparse 

class MyClass: 
    def StartWork(self, issueNumber, **kwargs): 
     if issueNumber is None: 
      issueNumber = input("please enter an issue number: ") 
     else: 
      print("issue number detected") 
     print(issueNumber) 

parser = argparse.ArgumentParser() 
subparsers = parser.add_subparsers(dest='MyClass-command', help='Command to perform') 
subparsers.required = True 
startWorkParser = subparsers.add_parser('startwork', help='Command to begin work on a new branch') 
startWorkParser.add_argument("issuenumber", type=int, help="The issue number used to create a local branch based on the specified issue number", nargs='?', default=None) 
startWorkParser.set_defaults(func=MyClass.StartWork) 

# Parse the arguments to make sure we have all the information requried to actually do something. 
args = parser.parse_args() 
mc = MyClass() 

try: 
    args.func(mc, **vars(args)) 
except AssertionError as e: 
    print("Error: "+str(e)) 

# Parse the arguments to make sure we have all the information required to actually do something. 
args = parser.parse_args() 

ich einen Anruf wie folgt erwartet:

python MyClass.py startwork 

... in den Benutzer zu führen, dass eine Ausgabenummer aufgefordert. Stattdessen erhalte ich:

Traceback (most recent call last): 
    File "C:\Projects\RedmnieGlue\MyClass.py", line 23, in <module> 
    args.func(mc, **vars(args)) 
TypeError: StartWork() missing 1 required positional argument: 'issueNumber' 

Warum ist die nargs='?' hier nicht vorherrschend?

bearbeiten

Wenn ich es so nennen:

python MyClass.py startwork -h 

ich dieses:

usage: class1.py startwork [-h] [issuenumber] 

positional arguments: 
    issuenumber The issue number used to create a local branch based on the 
       specified issue number 

optional arguments: 
    -h, --help show this help message and exit 

..., die (auf der Basis der [] um issuenumber) schlägt Ich es ist Verständnis, dass ein optionales Argument ist, aber etwas g verhindert, dass es so funktioniert, wie ich es erwarte. Etwas mit meiner Verwendung von subparsers und Aufruf von Methoden mit dem Arg-Parser vielleicht zu tun?

+0

Ich kann diesen Code ohne Fehler ausführen. –

+1

(1) Es gibt einen Syntaxfehler in 'def StartWork (...)' (fehlender abschließender Doppelpunkt). (2) Die Fehlermeldung stimmt nicht mit dem angezeigten Code überein (z. B. gibt es keine 'Main'-Funktion). Daher wird in der vereinfachten Version nicht angezeigt, was mit Ihrem Code falsch ist. – poke

+0

Es war ein Versuch, den ursprünglichen Code in ein praktikables Beispiel zu zerlegen. Ich werde es reparieren, damit es eine komplette Arbeitslösung ist ... –

Antwort

2

Wenn drucken Sie den Inhalt vars(args) vor Ihrer Funktionsaufruf wie folgt aus:

print(vars(args)) 
args.func(mc, **vars(args)) 

Dann können Sie leicht prüfen, ob es etwas falsch mit dem Argument Parser ist oder nicht. Mit einem Aufruf des Skripts ohne Argumente (z python myscript.py), erhalten Sie die folgende Ausgabe:

{'MyClass-command': 'startwork', 'issuenumber': None, 'func': <function MyClass.StartWork at 0x000000493898C510>} 

Wie Sie issuenumber tatsächlich in diesem Wörterbuch ist zu sehen, und es hat den Standardwert erhalten. Der Fehler, den Sie sehen, liegt nicht am Argument-Parser (es ist auch kein Arg-Fehler, daher ist die Überprüfung der Argumente - issuenumber ist optional) - absolut korrekt.

Statt dessen, was falsch läuft, ist, dass das Argument issuenumber ist nicht auf das Argument Positionsübergeben, wenn **vars(args) verwenden. Der Grund dafür ist eigentlich ganz einfach:

Der Wörterbuchschlüssel ist issuenumber; Die Funktion erwartet einen issueNumber (beachten Sie den Großbuchstaben N). Ändern Sie also entweder die Funktion, um einen Kleinbuchstaben issuenumber zu verwenden, oder ändern Sie stattdessen den Argumentparser zu store the value in issueNumber.

+0

Gut erkannt auf die Quelle des Fehlers @poke und die Einstellung 'issueNumber = None' in der Definition der' StartWork'-Methode bewirkt, dass es wie erwartet funktioniert, sobald der Fall der Methode mit dem der Argumentdefinition übereinstimmt. –

+0

Nur noch eine Sache zu beachten; Wenn der Name so festgelegt wird, dass er immer dem entspricht, was "StartWork" benötigt, funktioniert das sehr gut: 'inspect.getargspec (MyClass.StartWork) .args [1]' –

Verwandte Themen