Argparse argomenti posizionali opzionali?


652

Ho una sceneggiatura che dovrebbe essere usata in questo modo: usage: installer.py dir [-h] [-v]

dir è un argomento posizionale definito in questo modo:

parser.add_argument('dir', default=os.getcwd())

Voglio dirche sia facoltativo: quando non è specificato dovrebbe essere cwd.

Sfortunatamente quando non specifico l' dirargomento, ottengo Error: Too few arguments.

Risposte:


825

Usa nargs='?'(o nargs='*' se avrai bisogno di più di una directory)

parser.add_argument('dir', nargs='?', default=os.getcwd())

esempio esteso:

>>> import os, argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-v', action='store_true')
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('dir', nargs='?', default=os.getcwd())
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]

positional arguments:
  dir

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

14
Fare la ?e *significano la stessa cosa significano nelle espressioni regolari (cioè ?richiede 0 o 1, e *richiedendo 0 o più)? In tal caso, +funziona anche?
Dolan Antenucci,

37
@dolan: Sì, +funziona anche. Vedi docs.python.org/2/library/argparse.html#nargs per i dettagli.
Vinay Sajip,

2
c'è un modo per far sì che dir si presenti in argomenti opzionali? o sembra che gli argomenti posizionali dovrebbero avere un qualificatore 'opzionale' precedente. è possibile registrarsi (per quanto riguarda l'aiuto) in quanto tale?
scagnetti,

6
@ant Da quanto sopra, puoi vedere che dir è facoltativo (che appare tra parentesi quadre nell'output di argparse indica questo).
Vinay Sajip,

1
Tx! Accedi a dir options.dir, no args.dir, come stavo provando!
ptim

69

Come estensione alla risposta @VinaySajip. Ci sono ulteriori nargsdegne di nota .

  1. parser.add_argument('dir', nargs=1, default=os.getcwd())

N (un numero intero). N argomenti dalla riga di comando verranno raccolti in un elenco

  1. parser.add_argument('dir', nargs='*', default=os.getcwd())

'*'. Tutti gli argomenti della riga di comando presenti vengono raccolti in un elenco. Si noti che in genere non ha molto senso avere più di un argomento posizionale con nargs='*', ma nargs='*'sono possibili più argomenti opzionali con .

  1. parser.add_argument('dir', nargs='+', default=os.getcwd())

'+'. Proprio come '*', tutti gli argomenti della riga di comando presenti vengono raccolti in un elenco. Inoltre, verrà generato un messaggio di errore se non era presente almeno un argomento della riga di comando.

  1. parser.add_argument('dir', nargs=argparse.REMAINDER, default=os.getcwd())

argparse.REMAINDER. Tutti gli altri argomenti della riga di comando vengono raccolti in un elenco. Ciò è comunemente utile per le utility della riga di comando che inviano ad altre utility della riga di comando

Se l' nargsargomento della parola chiave non viene fornito, il numero di argomenti consumati viene determinato dall'azione. In genere ciò significa che verrà utilizzato un singolo argomento della riga di comando e verrà prodotto un singolo elemento (non un elenco).

Modifica (copiato da un commento di @Acumenus) nargs='?' I documenti dicono: '?'. Un argomento verrà consumato dalla riga di comando, se possibile, e prodotto come un singolo elemento. Se non è presente alcun argomento della riga di comando, verrà prodotto il valore predefinito.


3
Va notato tuttavia che nargs='?'non produce un elenco.
Acumenus,

@ABB Ultima riga della risposta Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced.Spero che questo aiuti ...
Matas Vaitkevicius,

1
La riga tra virgolette si riferisce al caso di non definire nargs, ma lo nargs='?'sta definendo. I documenti dicono: "?". Se possibile, verrà utilizzato un argomento dalla riga di comando e prodotto come un singolo elemento. Se non è presente alcun argomento della riga di comando, verrà prodotto il valore predefinito.
Acumenus,

@ABB Modifica la risposta se ritieni che manchi qualcosa. Grazie.
Matas Vaitkevicius,

Qual è la differenza tra nargs=argparse.REMAINDERe nargs='*', come mi sembra, sono identici nel loro effetto (testati in Python 2.7.10 e Python 3.6.1)?

-5

parser.add_argumentha anche un interruttore richiesto . È possibile utilizzare required=False. Ecco un frammento di esempio con Python 2.7:

parser = argparse.ArgumentParser(description='get dir')
parser.add_argument('--dir', type=str, help='dir', default=os.getcwd(), required=False)
args = parser.parse_args()

11
OP stava chiedendo dei parametri posizionali, non '--dir'. 'richiesto' è un argomento non valido per i posizionali. E "falso" era un errore di battitura, intendeva "falso". +1 per i principianti, -1 per la sciattezza.
SoloPilot il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.