简体   繁体   中英

Use either one flag argument or two positional arguments with argparse

i'm stuck on a task, which require either 2 positional args or 1 (a file) if flag enabled:

parser.add_argument('pos_arg1', help='desc')
parser.add_argument('pos_arg2', help='desc')
parser.add_argument('--add_arg1', help='desc', type=argparse.FileType('r'), nargs='?')

so using the script with either script.py arg1 arg2 or script.py --add_arg1 file are both valid. How would I do this?

If you define:

In [422]: parser=argparse.ArgumentParser()    
In [423]: g=parser.add_mutually_exclusive_group()
In [424]: g.add_argument('--foo')
In [426]: g.add_argument('bar',nargs='*',default='test')

In [427]: parser.print_help()
usage: ipython2.7 [-h] [--foo FOO | bar [bar ...]]

positional arguments:
  bar

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

In [429]: parser.parse_args([])
Out[429]: Namespace(bar='test', foo=None)

In [430]: parser.parse_args(['one','two'])
Out[430]: Namespace(bar=['one', 'two'], foo=None)

In [431]: parser.parse_args(['--foo','two'])
Out[431]: Namespace(bar='test', foo='two')

With this you can specify two (really any number) of unlabeled values, or one value flagged with --foo . It will object if I try both. I could have marked the group as required .

A couple of notes:

Marking --foo as nargs='?' is relatively meaningless unless I specify both a default and const .

I can only specify one one positional in the exclusive group, and that argument has to have '?' or '*', and a 'default'. In other words, it has to genuinely optional.

Without the mutually_exclusive_group I could make both positionals ? , but I can't say 'zero or two arguments'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM