Python argparse带有标志的选择参数的正确格式

时间:2019-10-15 13:51:38

标签: python formatting posix argparse

我正在尝试使用Python的argparse为“选择”类型的命令行参数创建格式正确的帮助消息。对于命令,我允许使用名称“ --operation”和别名“ -o”。目前,argparse正在帮助消息中的两个选项旁边打印选项列表。

请注意,此问题与格式化选项帮助消息 的问题不同(Athon在此问题有一个很好的答案:Python argparse: How to insert newline in the help text?

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-o', '--operation', help="operation to perform", type=str, choices=["create", "update", "delete"])
_StoreAction(option_strings=['-o', '--operation'], dest='operation', nargs=None, const=None, default=None, type=<class 'str'>, choices=['create', 'update', 'delete'], help='operation to perform', metavar=None)
>>> parser.print_help()
usage: [-h] [-o {create,update,delete}]

optional arguments:
  -h, --help            show this help message and exit
  -o {create,update,delete}, --operation {create,update,delete}
                        operation to perform
>>> 

我的问题是这一行:

  -o {create,update,delete}, --operation {create,update,delete}

如何将选项列表重复两次非常笨拙。特别是因为我将拥有更长的列表。我认为最好是这样:

-o, --operation {create,update,delete}

这当然是假设没有关于它如何工作的POSIX规则。我认为没有。

如何获得所需的输出?还是有一个我不应该尝试的充分理由?

1 个答案:

答案 0 :(得分:1)

这是一个很不错的技巧,但是似乎没有一个很好的地方可以抓住它。

定义您自己的格式化程序,该格式化程序将覆盖_format_action_invocation方法(基本上是通过复制)。您所做的唯一更改是仅将选择添加到 last 选项字符串。

class MyHelpFormatter(HelpFormatter):

    def _format_action_invocation(self, action):
        if not action.option_strings:
            default = self._get_default_metavar_for_positional(action)
            metavar, = self._metavar_formatter(action, default)(1)
            return metavar

        else:
            parts = []

            # if the Optional doesn't take a value, format is:
            #    -s, --long
            if action.nargs == 0:
                parts.extend(action.option_strings)

            # if the Optional takes a value, format is:
            #    -s ARGS, --long ARGS
            else:
                default = self._get_default_metavar_for_optional(action)
                args_string = self._format_args(action, default)
                for option_string in action.option_strings[:-1]:
                    parts.append('%s' % (option_string,))
                parts.append('%s %s' % (action.option_strings[-1], args_string)
            return ', '.join(parts)