C'è un bug report su questo: http://bugs.python.org/issue9338
optional argparse con nargs =, '*' o '+' non può essere seguito da positionals
Un semplice '?' (utente) correzione è di usare --
per separare postionals da optionals:
./test.py -o 0.21 0.11 0.33 0.13 -- 100
ho scritto una patch che riserva alcuni degli argomenti per l'utilizzo da parte del positio nale. Ma non è banale.
Per quanto riguarda la modifica della linea di utilizzo - la cosa più semplice è quello di scrivere il proprio, per es .:
usage: test.py [-h] positional [-o OPTIONAL [OPTIONAL ...]]
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] -- positional
non mi consiglia di aggiungere la logica per il formattatore utilizzo per rendere questo tipo di cambiamento. Penso che diventerebbe troppo complesso.
Un'altra soluzione rapida consiste nel trasformare questo posizionale in un (obbligatorio) facoltativo. Dà all'utente completa libertà per quanto riguarda il loro ordine e potrebbe ridurre la confusione. Se non si vuole confondere un 'optional richiesto' basta dargli un valore logico predefinito.
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] -p POSITIONAL
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] [-p POS_WITH_DEFAULT]
Una semplice modifica al Help_Formatter è quello di elencare semplicemente gli argomenti nell'ordine in cui sono definite.Il modo normale di modificare il comportamento del formattatore consiste nel suddividerlo in sottoclasse e cambiare uno o due metodi. Molti di questi metodi sono "privati" (prefisso _), quindi lo fai con la consapevolezza che il codice futuro potrebbe cambiare (lentamente).
In questo metodo, actions
è l'elenco di argomenti, nell'ordine in cui sono stati definiti. Il comportamento predefinito è dividere gli "optionals" da "positionals" e riassemblare l'elenco con positionals alla fine. C'è un codice aggiuntivo che gestisce le lunghe code che necessitano di un wrapping. Normalmente mette posizionali su una linea separata. L'ho omesso.
class Formatter(argparse.HelpFormatter):
# use defined argument order to display usage
def _format_usage(self, usage, actions, groups, prefix):
if prefix is None:
prefix = 'usage: '
# if usage is specified, use that
if usage is not None:
usage = usage % dict(prog=self._prog)
# if no optionals or positionals are available, usage is just prog
elif usage is None and not actions:
usage = '%(prog)s' % dict(prog=self._prog)
elif usage is None:
prog = '%(prog)s' % dict(prog=self._prog)
# build full usage string
action_usage = self._format_actions_usage(actions, groups) # NEW
usage = ' '.join([s for s in [prog, action_usage] if s])
# omit the long line wrapping code
# prefix with 'usage:'
return '%s%s\n\n' % (prefix, usage)
parser = argparse.ArgumentParser(formatter_class=Formatter)
che produce una linea di utilizzo come:
usage: stack26985650.py [-h] positional [-o OPTIONAL [OPTIONAL ...]]