2013-08-16 24 views
18

Con l'argparse di python, come posso rendere un sottocomando un argomento obbligatorio? Voglio farlo perché voglio argparse di errore se non viene specificato un sottocomando. Sostituisco il metodo di errore per stampare invece la guida. Ho sottocomandi nidificati a 3 profondità, quindi non si tratta semplicemente di gestire argomenti zero al livello più alto.argparse con i sottocomandi richiesti

Nell'esempio seguente, se questo si chiama in questo modo, ottengo:

$./simple.py 
$ 

Quello che voglio fare è invece per argparse a lamentarsi che il sottocomando richiesta non è stato specificato:

import argparse 

class MyArgumentParser(argparse.ArgumentParser): 
    def error(self, message): 
     self.print_help(sys.stderr) 
     self.exit(0, '%s: error: %s\n' % (self.prog, message)) 

def main(): 
    parser = MyArgumentParser(description='Simple example') 
    subs = parser.add_subparsers() 
    sub_one = subs.add_parser('one', help='does something') 
    sub_two = subs.add_parser('two', help='does something else') 

    parser.parse_args() 

if __name__ == '__main__': 
    main() 

risposta

31

C'è stato un cambiamento di 3.3 nel messaggio di errore per gli argomenti richiesti, ei sottocomandi si sono persi nella polvere.

http://bugs.python.org/issue9253#msg186387

Vi suggerisco questo lavoro intorno, impostando l'attributo required dopo la subparsers è definito.

parser = ArgumentParser(prog='test') 
subparsers = parser.add_subparsers() 
subparsers.required = True 
subparsers.dest = 'command' 
subparser = subparsers.add_parser("foo", help="run foo") 
parser.parse_args() 
+0

Eccellente, questo è quello di cui avevo bisogno. Funziona alla grande ora e guarderò la correzione del bug. – PonyEars

0

Che ne dici di usare required=True? Maggiori informazioni here.

+4

Non è supportato dai 'add_subparsers()' Metodo: 'TypeError: __init __() ha ottenuto un argomento chiave inaspettato 'required'' – Bakuriu

+1

Ah, hai ragione. Colpa mia. –

+0

Stiamo aggiungendo questo a Python 3.7 e rendendolo il comportamento predefinito. Meglio tardi che mai ¯ \\ _ (ツ) _/¯ –

0

È possibile utilizzare l'argomento dest, che è documentata nell'ultimo esempio nella documentazione per add_subparsers():

# required_subparser.py 
import argparse 

parser = argparse.ArgumentParser() 
subparsers = parser.add_subparsers(dest='subparser_name') 
one = subparsers.add_parser('one') 
two = subparsers.add_parser('two') 

args = parser.parse_args() 

Esecuzione:

$python required_subparser.py 
usage: required_subparser.py [-h] {one,two} ... 
required_subparser.py: error: too few arguments 
$python required_subparser.py one 
$# no error 
+0

Non so se mi manca qualcosa qui, ma non ricevo il messaggio "uso:" quando eseguo il tuo esempio. Torno al prompt senza output con o senza argomento. Sto usando Python 3.3.2 e l'argparse che è venuto con esso. – PonyEars

+1

@redstreet Non hai menzionato che stavi usando python3.3 e l'ho provato usando l'eseguibile di sistema 'python', che è python 2.7. Effettivamente con python3.3 non si ottengono i messaggi. – Bakuriu

+0

Sì, perché non mi aspettavo che ciò fosse dovuto a un bug (che lo rendeva dipendente dalla versione!). Grazie per la risposta e per aver provato su 2.7! – PonyEars

Problemi correlati