2014-04-10 9 views
9

Następujący kod, używając argumentów argparse, kończy się niepowodzeniem w Pythonie 3, ale działa zgodnie z oczekiwaniami w Pythonie 2. Po porównaniu dokumentów nadal nie mogę określić przyczyny.Dlaczego ten kod argarse zachowuje się inaczej między Python 2 a 3?

#!/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) 

Wyjście z Python 2.7.6 jest:

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

W Python 3.3.5, otrzymuję:

[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

Należy zauważyć, że jeśli użyjesz parametru "parser": 'args = cmd.parse_args()' to zadziała. – alecxe

+0

Ten kod wydaje się dawać mi ten sam błąd w Pythonie 2.7.4. Najprawdopodobniej używasz niewłaściwej wersji pliku lub czegoś. To nie powinno działać. Spróbuj jeszcze raz ostrożniej. – bosnjak

+0

Kiedy wpisuję twój kod w interpreterze Python 2.7.6, pojawia się ten sam błąd w wierszu 'args = ap.parse_args()'. –

Odpowiedz

12

najnowszy argparse uwolnienie zmieniło, jak testowane na wymaganych argumentów i niesprawiedliwi wpadli przez szczeliny. Nie są już "wymagane". http://bugs.python.org/issue9253#msg186387

Po otrzymaniu numeru test.py: error: too few arguments pojawia się informacja, że ​​nie podano mu argumentu "podpolecenia". W wersji 3.3.5 wykracza poza ten krok i zwraca args.

Dzięki tej zmianie 3.3.5 powinien zachowywać się tak samo jak we wcześniejszych wersjach:

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

Uwaga - zarówno dest i required muszą być ustawione. dest jest potrzebny, aby nadać temu argumentowi nazwę w komunikacie o błędzie.


Ten błąd:

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

został wyprodukowany ponieważ cmd subparser nie prowadziła i nie umieścić swoje argumenty (domyślnie lub nie) do nazw. Efekt ten można zobaczyć, definiując inny poziomy i patrząc na wynikowy kod args.

+1

Dzięki, że to przybili. W przypadku jakichkolwiek wątpliwości, to rozwiązanie jest kompatybilne z Pythonem 2.7 – Wedgwood

Powiązane problemy