2013-04-02 19 views
22

Vorrei fare queste invocazioni di myprog e non altre.come rendere l'argomento opzionale in python argparse

$ python3 myprog.py -i infile -o outfile 
$ python3 myprog.py -o outfile 
$ python3 myprog.py -o 
$ python3 myprog.py 

In particolare, desidero rendere illegale specificare l'infile ma non il file di output.

Nel terzo caso, si presuppone un nome predefinito per il file di uscita, "out.json." Nel secondo, terzo e quarto caso, viene assunto un nome predefinito per il file di input, "file.n.json", dove n è un numero di versione intero. Nel quarto caso il file di output sarebbe "file.n + 1.json" dove n + 1 è un numero di versione uno più grande di quello sul file di input. La sezione del mio codice è:

import argparse 

parser = argparse.ArgumentParser(description="first python version") 
parser.add_argument('-i', '--infile', nargs=1, type=argparse.FileType('r'), help='input file, in JSON format') 
parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format') 

args = parser.parse_args() 

print("Here's what we saw on the command line: ") 
print("args.infile",args.infile) 
print("args.outfile",args.outfile) 

if args.infile and not args.outfile: 
    parser.error("dont specify an infile without specifying an outfile") 
elif not args.infile: 
    print("fetching infile") 
else: # neither was specified on the command line 
    print("fetching both infile and outfile") 

Il problema è che, quando si esegue

$ python3 myprog.py -i infile.json 

invece che l'errore parser che speravo, ottengo:

Here's what we saw on the command line: 
args.infile [<_io.TextIOWrapper name='infile.json' mode='r' encoding='UTF-8'>] 
args.outfile <_io.TextIOWrapper name='out.json' mode='w' encoding='UTF-8'> 
fetching both infile and outfile 

... il che suggerisce che anche se non c'era alcun "-o" sulla riga di comando, funzionava come se ci fosse.

+0

Qual è la differenza tra il 3 ° e il 4 ° caso? cosa significa il -o? –

+0

Il quarto caso utilizza nomi di file di estensione e di file predefiniti (in particolare file.n.json e file.n + 1.json, ovvero i file con numeri di versione incorporati). Questi sono diversi da "out.json", che è ciò che causerebbe il terzo caso con l'opzione "-o". Ho modificato il testo sopra per indicare questo. – user1416227

+0

Come si suppone che il quarto caso funzioni come opzione '--input' non ha un valore predefinito? – maxschlepzig

risposta

10

È stato specificato un argomento predefinito per il file di uscita.

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), default='out.json', help='output file, in JSON format') 

Se l'opzione -o non è specificato nella riga di comando, il parser arg inserisce l'argomento predefinito.

Modifica questo:

parser.add_argument('-o', '--outfile', nargs='?', type=argparse.FileType('w'), help='output file, in JSON format') 

e le cose dovrebbero funzionare come previsto.


Se si vuole essere in grado di specificare -o, senza un nome di file, probabilmente si desidera qualcosa di simile:

out_file = args.out if args.out is not None else 'json.out'

Non sono sicuro se il parametro relativo sarà None o '' (cioè, stringa vuota) se si specifica il -o senza un parametro - ho il sospetto che sia None, ma non lo so per certo. Dovrai testarlo per essere sicuro.

Non so come farlo senza logica aggiuntiva con argparse.

+1

È quasi esattamente quello che voglio. Il problema rimanente è che voglio '$ python3 myprog.py -o' per agire come se avessi eseguito' $ python3 myprog.py -o out.json'. Puoi suggerire come farlo accadere? – user1416227

+0

Grazie! Pensavo di poterlo fare con argparse. – user1416227

+0

Questa risposta ignora i requisiti del terzo caso dalla domanda. Vedi la risposta di maximi su come il terzo caso può essere implementato con argparse. L'ultimo compito non è nemmeno la sintassi Python valida. – maxschlepzig

13

Come un add-on per la risposta selezionata:

L'opzione per eseguire -o senza specificare un file, può essere fatto utilizzando const combinato con nargs='?'.

Dalla documentazione:

Quando add_argument() viene chiamato con stringhe di opzione (come -f o --foo) e nargs = '?'. Questo crea un argomento facoltativo che può essere seguito da con zero o con un argomento da riga di comando.Quando si analizza la riga di comando, se si incontra la stringa di opzioni senza alcun argomento da riga di comando , verrà assunto invece il valore di const. Vedi la descrizione di nargs per gli esempi.

+0

Questa dovrebbe essere la risposta corretta. Grazie!! – jbo5112

Problemi correlati