max_help_position 在 python argparse 库中不起作用

2023-12-22

嗨,同事,我有代码(max_help_position 是 2000):

formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=2000)
parser = argparse.ArgumentParser(formatter_class=formatter_class)


subparsers = parser.add_subparsers(title="Commands", metavar="<command>")

cmd_parser = subparsers.add_parser('long_long_long_long_long_long_long',
                                   help='- jksljdalkjda',
                                   formatter_class=formatter_class)

args = parser.parse_args(['-h'])
print args

we have

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

Commands:
  <command>
    long_long_long_long_long_long_long
                                      - jksljdalkjda
    small                             - descr

instead

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

Commands:
  <command>
    long_long_long_long_long_long_long - jksljdalkjda
    small                              - descr

您知道如何解决这个问题吗?

代码:

class MyFormatter(argparse.HelpFormatter):
    def __init__(self, prog):
        super(MyFormatter, self).__init__(prog, max_help_position=2000)
        self._max_help_position = 2000
        self._action_max_length += 4

formatter_class = MyFormatter
parser = argparse.ArgumentParser(formatter_class=formatter_class)

得到相同的结果。

代码(宽度=2000)

formatter_class = lambda prog: argparse.HelpFormatter(prog,
                  max_help_position=2000, width=2000)

得到相同的结果。

谢谢。

附:还有一些额外的小问题:这是“可选参数”中的奇怪空格。您知道如何分隔“命令”和“可选参数”吗?因为“可选参数”中没有空格,而“命令”中有空格,因为它们本质不同?


您还需要增加宽度

try:

formatter_class=lambda prog: argparse.HelpFormatter(prog,
    max_help_position=100, width=200)

正如我之前的想法(如下)所示,格式设置考虑了整体宽度以及 max_position 值。


(之前)

在我有限的测试中,您的格式化程序子类似乎可以工作。但我还没有突破极限。

您可能需要更多地研究格式化程序代码。

例如有一个format_action实际使用 max_width 的方法

def _format_action(self, action):
    # determine the required width and the entry label
    help_position = min(self._action_max_length + 2,
                        self._max_help_position)
    help_width = self._width - help_position
    action_width = help_position - self._current_indent - 2
    ...

请注意,它与宽度相互作用。然后它继续实际格式化帮助行并执行换行。所以实际的实现并不简单。

我没有关注你关于空间的问题。format_help命令格式化程序格式化多个部分(包括参数组)。这些部分(通常)以几个换行符结束。组装它们后,格式化程序会删除“不必要的”换行,在组之间留下一个空格。子解析器不适合其他类别,因此我必须研究代码才能准确了解它是如何处理的。


Your lambda定义也有效。我以前没见过,而且我认为这不是开发人员的意图,但是 Python 并不重要——如果它有效的话。

通过使用值和字符串,我发现 max_position 最多可达 56 左右。然后它就有点粘了。但如果我也改变width(默认来自控制台),我可以进一步增加 max_position 。


我用很长的时间测试了这个parser争论。添加

parser.add_argument('-l','--long','--longlonglonglong', help='help after long option strings')

产生:

usage: issue25297.py [-h] [-l LONG] <command> ...

optional arguments:
  -h, --help                                     show this help message and
                                                 exit
  -l LONG, --long LONG, --longlonglonglong LONG  help after long option
                                                 strings

Commands:
  <command>
    long_long_long_long_long_long_long           - jksljdalkjda

So max_help_position确实适用于常规解析器格式。但由于某种原因,当只有子解析器名称很长时,它就不会。该部分需要一些特殊的格式。它是缩进的,并且子解析器名称不是真正的操作(参数),而是选择subparsers争论。我会更详细地研究它。

子解析器名称字符串缩进了 2 个额外字符(与其他参数相比)。收集到的代码self._action_max_length没有考虑到这一点。因此,如果子解析器名称是最长的字符串,则此 max_length 将少 2 个空格。比较实际的 v 期望值:

long_long_long_long_long_long_long
                                  - jksljdalkjda
long_long_long_long_long_long_long  - jksljdalkjda

(格式化分两步完成;一次计算这样的值_action_max_length,并第二次产生实际输出)。

子解析器通过递归调用进行格式化_format_action,所以我对简单的修复并不乐观。


更正格式化程序

这是一个经过修补的格式化程序,它可以正确解释子操作(子解析器)的缩进。当参数(动作)添加到格式化程序时,该函数会计算其调用字符串的宽度,并调整 self._max_action_length。后者用于缩进帮助字符串。

class MyFormatter(argparse.HelpFormatter):
    """
    Corrected _max_action_length for the indenting of subactions
    """
    def add_argument(self, action):
        if action.help is not argparse.SUPPRESS:

            # find all invocations
            get_invocation = self._format_action_invocation
            invocations = [get_invocation(action)]
            current_indent = self._current_indent
            for subaction in self._iter_indented_subactions(action):
                # compensate for the indent that will be added
                indent_chg = self._current_indent - current_indent
                added_indent = 'x'*indent_chg
                invocations.append(added_indent+get_invocation(subaction))
            # print('inv', invocations)

            # update the maximum item length
            invocation_length = max([len(s) for s in invocations])
            action_length = invocation_length + self._current_indent
            self._action_max_length = max(self._action_max_length,
                                          action_length)

            # add the item to the list
            self._add_item(self._format_action, [action])

它的使用示例(没有广泛使用):

# call class with alternate parameters
formatter_class=lambda prog: MyFormatter(prog, max_help_position=40,width=100)

parser = argparse.ArgumentParser(formatter_class=formatter_class)

parser.add_argument('-l','--long', help='help after long option strings')

subparsers = parser.add_subparsers(title="Commands", metavar="<command>")

cmd_parser = subparsers.add_parser('long_long_cmd',
                                   help='longish command',
                                   formatter_class=formatter_class,
                                   aliases=['long', 'long_cmd'])
                                   # newer arpgarse take aliases
sht_parser = subparsers.add_parser('short', help = 'short cmd')

args = parser.parse_args(['-h'])

显示:

usage: issue25297.py [-h] [-l LONG] <command> ...

optional arguments:
  -h, --help                        show this help message and exit
  -l LONG, --long LONG              help after long option strings

Commands:
  <command>
    long_long_cmd (long, long_cmd)  longish command
    short                           short cmd
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

max_help_position 在 python argparse 库中不起作用 的相关文章

随机推荐