Python3 Argparse metavar brackets parsed weirdly

 ̄綄美尐妖づ 提交于 2019-12-25 03:33:23

问题


I am using argparse in python3, and I get some strange things:

A short version of code that I'm using is:

argparser = argparse.ArgumentParser(description='add/remove items')
argparser.add_argument('-a', action='append',     metavar="Item(s)", help='add one or more items to the list')
argparser.add_argument('-r', action='append',     metavar="Item(s)", help='remove one or more items from the list')
args = argparser.parse_args()

When I run the script with the -h flag, I get this output:

usage: test.py [-h] [-a Items)] [-r Item(s]

add/remove items

optional arguments:
  -h, --help  show this help message and exit
  -a CPE(s)   add one or more items to the list
  -r CPE(s)   remove one or more items from the list

Mind the weird parsing of the brackets in the first line.

What causes this, and how do I solve this?


回答1:


Since you want to have the possibility of having multiple items. Another way to do this with argparse is as follows:

import argparse
argparser = argparse.ArgumentParser(description='add/remove items')
argparser.add_argument('-a', metavar="item", nargs="*", help='add one or more items to the list')
argparser.add_argument('-r', metavar="item", nargs="*", help='remove one or more items from the list')
args = argparser.parse_args()

The key point is the use of nargs="*" (0 or more arguments). The help becomes:

usage: test.py [-h] [-a [item [item ...]]] [-r [item [item ...]]]

This way, you do not have to use "Item(s)", and you also follow a standard practice.

PS: I see what you wanted to do. With action="append", you are actually allowing the user to specify multiple -a and -r options. In this case, you should definitely write "Item" (and not "Item(s)"), since each option takes a single item. This solves your problem too (your help message should indicate that multiple -a and -r options can be given).




回答2:


It's the () in your metavars that is causing the mangled usage. The usage formatter uses () to mark require mutually exclusive groups, and then removes surplus ones. So it tries to keep ( -o | -t), but change (-o) to -o. Unfortunately that code does not distinguish between the ones it added and the ones you added via the metavar (or help line).

Your line was formatted as:

usage: test.py [-h] [-a Item(s)] [-r Item(s)]

but it removed the outer pair of () which I have replaced with *:

usage: test.py [-h] [-a Item*s)] [-r Item(s*]

http://bugs.python.org/issue11874 focuses on a different usage problem, one which occurs when the usage line is long and needs to be split. But the last 2 posts in that issue deal with this issue.

If you don't like the limitations of the automatic usage formatting, you can give the parser your own custom usage parameter.



来源:https://stackoverflow.com/questions/28234992/python3-argparse-metavar-brackets-parsed-weirdly

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