--
is a handy way of saying 'positional arguments start here'.
With your parser, these work:
program.py refresh # sets ids=None
program.py refresh --ids 1 2 3
program.py --ids 1 2 3 -- refresh
You could give the --ids
argument a default (e.g. []) if you don't like the None
.
Any problems with program.py refesh --ids 1,2,3
are due to how the shell splits your command line. Look at the sys.argv
list.
Problems with program.py --ids 1 2 3 refresh
arise because when handling --ids
, the parser tries to use all strings that follow that aren't obviously flags (e.g. with '-'). It does not use the 'int' type to test which ones to use and which to leave.
Now if the ids
were positional, it would handle the 1 2 3 refresh
:
parser.add_argument('ids',type=int,nargs='+')
parser.add_argument('cmd')
parser.parse_args('1 2 3 refresh'.split())
But that's because the parser uses a different strategy to allocate strings to several positional arguments. It uses a re
matcher that looks like A+A
.
Kevin's type
approach might be better implemented with a simple function:
def mytype(astring):
ll = astring.split(',')
return [int(l) for l in ll]
parser.add_argument('--ids', type=mytype)
It could be generalized to handle quoted strings like "1 2 3". type
can be any function that takes a string, and returns the desired value(s), and raises an error if it can't do the conversion.