2014-04-10 3 views
9

Der folgende Code, der die Subparser von argparse verwendet, schlägt auf Python 3 fehl, läuft aber wie erwartet in Python 2. Nach dem Vergleichen der Dokumente kann ich immer noch nicht sagen, warum.Warum verhält sich dieser Argarse-Code zwischen Python 2 und 3 anders?

#!/usr/bin/env python 
from __future__ import print_function 
from argparse import ArgumentParser 


def action(args): 
    print(args) 

if __name__ == '__main__': 
    std = ArgumentParser(add_help=False) 
    std.add_argument('standard') 

    ap = ArgumentParser() 
    sp = ap.add_subparsers() 

    cmd = sp.add_parser('subcommand', parents=[std], description='Do subcommand') 
    cmd.add_argument('arg') 
    cmd.set_defaults(do=action) 

    args = ap.parse_args() 
    args.do(args) 

Die Ausgabe von Python 2.7.6 ist:

[email protected]$ python test.py 
usage: test.py [-h] {subcommand} ... 
test.py: error: too few arguments 

In Python 3.3.5, die ich erhalten:

[email protected]$ python3 test.py 
Traceback (most recent call last): 
    File "test.py", line 21, in <module> 
    args.do(args) 
AttributeError: 'Namespace' object has no attribute 'do' 
+0

Beachten Sie, dass wenn Sie einen Subparser verwenden: 'args = cmd.parse_args()' würde es funktionieren. – alecxe

+0

Dieser Code scheint den gleichen Fehler für mich auf Python 2.7.4 zu geben. Höchstwahrscheinlich haben Sie die falsche Dateiversion oder etwas ähnliches. Es sollte nicht funktionieren. Probieren Sie es noch einmal vorsichtig. – bosnjak

+0

Wenn ich Ihren Code in einem Python 2.7.6 Interpreter eintippe, bekomme ich den gleichen Fehler in der Zeile 'args = ap.parse_args()'. –

Antwort

12

die neueste argparse Version geändert, wie es für erforderlich Argumente geprüft und Subparser fielen durch die Ritzen. Sie sind nicht mehr erforderlich. http://bugs.python.org/issue9253#msg186387

Wenn Sie test.py: error: too few arguments erhalten, ist es einwenden, dass Sie es nicht ein "Unterbefehl" -Argument geben. In 3.3.5 geht es über diesen Schritt hinaus und gibt args zurück.

Mit dieser Änderung 3.3.5 soll die gleichen wie frühere Versionen verhalten:

ap = ArgumentParser() 
sp = ap.add_subparsers(dest='parser') # dest needed for error message 
sp.required = True # force 'required' testing 

Hinweis - sowohl dest und required Bedarf eingestellt werden. dest wird benötigt, um diesem Argument einen Namen in der Fehlermeldung zu geben.


Dieser Fehler:

AttributeError: 'Namespace' object has no attribute 'do' 

produziert wurde, weil die cmd subparser nicht ausgeführt wurde, und hat setzen nicht seine Argumente (Standard oder nicht) in den Namensraum. Sie können diesen Effekt sehen, indem Sie einen anderen Subparser definieren und die resultierende args betrachten.

+1

Danke, das hat es genagelt. Falls es irgendein Wunder gab, ist diese Lösung abwärtskompatibel zu Python 2.7 – Wedgwood

Verwandte Themen