Python argparse: command-line argument that can be either named or positional -


i trying make python program uses argparse module parse command-line options.

i want make optional argument can either named or positional. example, want myscript --username=batman same thing myscript batman. want myscript without username valid. possible? if so, how can done?

i tried various things similar code below without success.

parser = argparse.argumentparser() group = parser.add_mutually_exclusive_group() group.add_argument("-u", "--user-name", default="admin") group.add_argument("user-name", default="admin") args = parser.parse_args() 

edit: above code throws exception saying valueerror: mutually exclusive arguments must optional.

i using python 2.7.2 on os x 10.8.4.

edit: tried gabriel jacobsohn's suggestion couldn't working correctly in cases.

i tried this:

parser = argparse.argumentparser() group = parser.add_mutually_exclusive_group() group.add_argument("-u", "--user-name", default="admin", nargs="?") group.add_argument("user_name", default="admin", nargs="?") args = parser.parse_args() print(args) 

and running myscript batman print namespace(user_name='batman'), myscript -u batman , myscript --user-name=batman print namespace(user_name='admin').

i tried changing name user-name user_name in 1st add_argument line , resulted in both batman , admin in namespace or error, depending on how ran program.

i tried changing name user_name user-name in 2nd add_argument line print either namespace(user-name='batman', user_name='admin') or namespace(user-name='admin', user_name='batman'), depending on how ran program.

the way argumentparser works, checks trailing positional arguments after has parsed optional arguments. if have positional argument same name optional argument, , doesn't appear anywhere on command line, it's guaranteed override optional argument (either default value or none).

frankly seems bug me, @ least when used in mutually exclusive group, since if had specified parameter explicitly have been error.

that said, suggested solution, give postional argument different name.

parser = argparse.argumentparser() group = parser.add_mutually_exclusive_group() group.add_argument('-u','--username') group.add_argument('static_username',nargs='?',default='admin') 

then when parsing, use optional username if present, otherwise fallback positional static_username.

results = parser.parse_args() username = results.username or results.static_username 

i realise isn't particularly neat solution, don't think of answers be.


Comments