argparse:删除 --help 中标志后的空格并使用 colorama 着色帮助输出

argparse: Remove whitespace after flags in --help and colorizing help output with colorama

我已经使用 argparse 向脚本添加了一些 args,效果很好。现在我正在尝试格式化 --help 输出。我已将 metavar='' 添加到每个产生更清晰输出的标记中,但是在单个标记之后有 space 使文本变得奇怪。

问题

标志将显示为 -m , --model 而不是 -m, --model

带有 type=boolconstnargs 的标志显示为 -x [], --xip [],添加了额外的 space 和 []

没有找到太多关于如何清理它的信息。是否发现关于 python.org 的讨论认为额外的 space 是一个已知问题并且使用 metavar='' 并不理想。

示例代码:

import argparse
import colorama
from colorama import init, Fore, Style
init(autoreset=True)

parser = argparse.ArgumentParser(description=Fore.RED + 'Some descriptive Text and such' + Fore.WHITE, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
add_arg = parser.add_argument
add_arg('-m',   '--model',  type=str, default='model_name',                     help="some help text", metavar='')
add_arg('-d',   '--derp',   type=str, default='burp',                           help="some more help text", metavar='')
add_arg('-x',   '--xip',    type=bool, default=False, const=True, nargs='?',    help="some other help text", metavar='')
args = parser.parse_args()

运行 python script.py -h 产生:

usage: script.py [-h] [-m] [-d] [-x ]

Some descriptive Text and such # <-- this line displays as RED

optional arguments:
  -h, --help           show this help message and exit
  -m , --model         some help text (default: model_name)
  -d , --derp          some more help text (default: burp)
  -x [], --xip []      some other help text (default: False)

将 metavar 更改为 metavar='\b' 会产生以下结果:

usage: script.py [-h] [-m] [-d] [-x ]] # <- extra bracket ]

Some descriptive Text and such

optional arguments:
  -h, --help         show this help message and exit
  -m, --model    some help text (default: model_name)   # indent broken
  -d, --derp     some more help text (default: burp)    # indent broken
  -x ], --xip ]  some other help text (default: False)  # indent broken

着色输出

我还想知道如何使用 colorama 为 --help 输出正确着色。为描述着色很容易,但是尝试为标志添加颜色会产生预期的错误。如果之前添加了颜色以帮助工作,例如 help=Fore.YELLOW + 'some help text',但它会为它之后的所有内容着色,并且不能在它之后添加任何 Fore 而不会出错。将它添加到其他任何地方都会产生错误。

有没有办法定义如何为标志和帮助文本着色,也许在设置它们的地方之外?

除此之外,还有没有argparse格式化的包?我发现一些旧的不能正常工作但没有新的。

好吧,我在 SO 上找到了一些旧的 post 后设法弄明白了。

来自 This Post 的代码设置了一个 add_argument_group。然后添加参数并通过设置 help=argparse.SUPPRESS.

隐藏帮助文本

--help 中显示的实际文本是组的 titledescription。这使它变得非常容易,因为您只是在那时连接字符串,并且可以在需要时使用 + 轻松添加您的色彩样式。

来自 post 的代码:

parser = argparse.ArgumentParser(description='Postfix Queue Administration Tool',
        prog='pqa',
        usage='%(prog)s [-h] [-v,--version]',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        )
parser.add_argument('-l', '--list', action='store_true',
        help='Shows full overview of all queues')
g = parser.add_argument_group(title='information options',
        description='''-q, --queue <queue>     Show information for <queue>
-d, --domain <domain>   Show information about a specific <domain>''')
g.add_argument('-q', '--queue', action='store', metavar='', dest='queue',
        help=argparse.SUPPRESS)
g.add_argument('-d', '--domain', action='store', metavar='<domain>', dest='domain',
        help=argparse.SUPPRESS)
parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1')
parser.print_help()

我修改的示例代码基于 post:

import argparse
from colorama import init, Fore, Style
init(autoreset=True)

parser = argparse.ArgumentParser(
    description=Fore.LIGHTBLACK_EX + 'Some descriptive Text and such' + Fore.WHITE,
    prog='script.py',
    usage=Fore.WHITE + '%(prog)s [-m] [-d] [-x]',
    formatter_class=argparse.RawDescriptionHelpFormatter,
    )
g = parser.add_argument_group(title=Fore.LIGHTBLACK_EX + 'args',
        description=Fore.RED + '''
-m   --model        ''' + Fore.WHITE + Style.DIM + '''some help text       || default: model_name''' + Fore.RED + Style.NORMAL + '''
-d   --derp         ''' + Fore.WHITE + Style.DIM + '''some more help text  || default: burp''' + Fore.RED + Style.NORMAL + '''
-x   --xip          ''' + Fore.WHITE + Style.DIM + '''some other help text || default: False''' + Fore.RED + Style.NORMAL + '''\n\n''')
g.add_argument('-m',   '--model',   type=str, default='model_name',                      help=argparse.SUPPRESS, metavar='')
g.add_argument('-d',   '--derp',    type=str, default='burp',                            help=argparse.SUPPRESS, metavar='')
g.add_argument('-x',   '--xip',     type=str2bool, default=False, const=True, nargs='?', help=argparse.SUPPRESS, metavar='')

args = parser.parse_args()

输出:

usage: script.py [-m] [-d] [-x]

Some descriptive Text and such

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

args:
  
  -m   --model        some help text       || default: model_name
  -d   --derp         some more help text  || default: burp
  -x   --xip          some other help text || default: False

附上终端输出的图片:

最后,根据@hpaulj 的建议,I found this function 所以我可以更改 bool 的类型并确保它始终正确解析。

def str2bool(v):
    if isinstance(v, bool):
        return v
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError('Boolean value expected.')