Changing the metavar value in argparse only in arg

2019-02-20 13:40发布

问题:

My question is similar to argparse help without duplicate ALLCAPS question.

Though i would explain in brief what that question was and what my question is:
I'd like to display argparse help for my options the same way the default -h,--help is, without the ALLCAPS text after each option, or at least without the duplicated CAPS.

For example, with the following code:

#filename=temp.py
import argparse
p = argparse.ArgumentParser()
p.add_argument('-i', '--ini', help="use alternate ini file")
print '\n', p.parse_args()

now running python temp.py -h:

usage: temp.py [-h] [-i INI]

optional arguments:
  -h, --help         show this help message and exit
  -i INI, --ini INI  use alternate ini file

Now what I want is something like:

usage: 123.py [-h] [-i INI]

optional arguments:
  -h, --help         show this help message and exit
  -i, --ini INI      use alternate ini file

OR

usage: 123.py [-h] [-i INI]

optional arguments:
  -h, --help         show this help message and exit
  -i, --ini          use alternate ini file

To get the second one, the way is to change the default metavar in the line p.add_argument as:

p.add_argument('-i', '--ini', help="use alternate ini file")

and change the default usage statement in argparse.ArgumentParser().

But when number of optional arguments increases in my code, I find it difficult to modify the usage message by adding and deleting the argument according to the modification in my code.

Is there any other way of solving the problem of metavar without affecting the usage statement.

Also what if I want to have my help displayed as shown in the first case, where there is only one time INI after -i, --ini.

If I am getting wrong in showing help as -i, --ini INI or -i, --ini instead of -i INI, --ini INI please correct me with proper reason. (By getting wrong I mean, it the convention I am using will lead to confusion or misunderstanding in user)

回答1:

https://stackoverflow.com/a/9643162/901925 and https://stackoverflow.com/a/23941599/901925 and https://stackoverflow.com/a/16969505/901925

give a HelpFormatter._format_action_invocation(self, action) method modification that replaces '-i INI, --ini INI' with '-i, --ini INI'.

'-h, --help' doesn't have the CAPS string because help does not take an argument. The INI is just a place holder for that argument. The original just tries to be clear, you can use either -i 124 or --ini 124

The METAVAR parameter gives you control over that place holder, but it is used both in formatting the usage and the help.

If you don't want to go the custom HelpFormatter class route, you could still use the custom usage method. For example at some point during development, do usage = parser.format_usage(). Now change the parser so the metavar is '', and the usage is this new one.

parser = argparse.ArgumentParser()
a1 = parser.add_argument('-f','--foo',help='<foo> argument')
a2 = parser.add_argument('-b','--bar',metavar='CUSTOM',help='<CUSTOM> argunent')
a3 = parser.add_argument('-z','--baz', action='store_true', help='no argument')

usage = parser.format_usage()
parser.usage=usage   # grab original usage
for a in [a1,a2]:
    a.metavar=''   # 'blank' out the metavars that matter
parser.print_help()

produces:

usage: usage: stack30704631.py [-h] [-f FOO] [-b CUSTOM] [-z]

optional arguments:
  -h, --help   show this help message and exit
  -f , --foo   <foo> argument
  -b , --bar   <CUSTOM> argunent
  -z, --baz    no argument


回答2:

For a fast solution you can just set backspace character to a metavar.

p.add_argument('-i', '--ini', help="use alternate ini file", metavar='\b')

It will get you this:

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

If you want this:

  -i, --ini INI      use alternate ini file

You will have to modify help formatter. Answered here python argparse help message, disable metavar for short options?