Argparse shortcut option for combining other options

一个人想着一个人 提交于 2020-12-14 07:20:10

问题


Let's say I have an input file option and an output file option. How can I create an option that combines the two? For example:

$ ./my_script.py -i input.txt -o output.txt

could be combined as:

$ ./my_script.py --io input_output.txt

You might say that I could do -io to combine both options, but -io filename is a shortcut for -i -o filename, not -i filename -o filename.

I thought that it might be possible to add dest=('input', 'output') to my .add_argument() call, but that raised an error that dest must be a string.

I tried adding a mutually exclusive group with --io on one side and a group of -i and -o on the other side, but the help texts for -i and -o did not show up any more when the program was run with --help:

usage: myscript.py [-h] [--io] [-i INPUT] [-o OUTPUT]

optional arguments:
  -h, --help  show this help message and exit
  --io        Use file as both input and output

Also, the mutually exclusive part didn't seem to work. I am still allowed to call the script with --io and the individual -i and -o options, and no error is raised.

Here is my skeleton code:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-i", "--input", help="Input file")
parser.add_argument("-o", "--output", help="Output file")

parser.parse_args()

The code with groups:

import argparse

parser = argparse.ArgumentParser()

exclusive = parser.add_mutually_exclusive_group()
exclusive.add_argument("--io", help="Input and Output")

sub = exclusive.add_argument_group()
sub.add_argument("-i", "--input", help="Input file")
sub.add_argument("-o", "--output", help="Output file")

args = parser.parse_args()

if args.io:
    in_file = out_file = args.io
else:
    in_file = args.input
    out_file = args.output

回答1:


It is easier to explain why things don't work than to suggest a solution.

Yes, dest must be a string; there's no provision for a list or tuple of dest values. But your in_file = out_file = args.io addresses that issue just fine. You could have also used:

 args.in_file=args.out_file = args.io

There's nothing wrong with massaging the args values after parsing.

argument_group is not designed for nesting, nor is it a way of adding 'any' (or 'and') logic to the mutually_exclusive_group. Maybe in the distant future there will be a way of defining a full set of logical combinations, but not now. Actually it isn't hard to do the tests; it's hard to define the API and the usage formatting.

Also keep in mind that mutually_exclusive_group is used to format the usage and test for co_ocurrance of arguments, while argument_group is used to group argument help lines. Two very different purposes.

If -i was a store_true argument then -io filename would be understood as -i -o filename. But translating it too -i filename -o filename is not in the current code (and probably not common enough to warrant a patch).

If you still want to use -i, -o and --io (I prefer -- for 2 character flags) I can suggest a couple of things:

  • write a custom usage that demonstrates what you want. If it is hard to write a clear usage, then your design is probably too complicated.

  • do your own exclusive groups testing after parsing. args.in_file is None is a good way of testing whether a flag has been used or not. Another possibility is to define defaults such that you don't care which combination the user uses.




回答2:


Keep it simple--the exclusive groups code you showed didn't exclude using both forms anyway. Try this:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-i", "--input", help="Input file")
parser.add_argument("-o", "--output", help="Output file")
parser.add_argument("--io", help="Input and Output")

parser.parse_args()

if args.io:
    assert args.input is None and args.output is None
    args.input = args.output = args.io
else:
    assert args.input and args.output


来源:https://stackoverflow.com/questions/38024501/argparse-shortcut-option-for-combining-other-options

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!