max_help_position 在 python argparse 库中不起作用 [英] max_help_position is not works in python argparse library

查看:23
本文介绍了max_help_position 在 python argparse 库中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hi colleagues I have the code (max_help_position is 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

我们有

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

Commands:
  <command>
    long_long_long_long_long_long_long
                                      - jksljdalkjda
    small                             - descr

代替

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

Commands:
  <command>
    long_long_long_long_long_long_long - jksljdalkjda
    small                              - descr

你知道解决这个问题的简单方法吗?

Do you know simply way how to fix this?

代码:

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)

The code (with width=2000)

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

得到相同的结果.

谢谢.

附言还有一些额外的小问题:这是可选参数"中的奇怪空格.你知道如何区分命令"和可选参数",因为可选参数"没有空格,命令"中有空格,因为它们是不同的本质?

P.S. Also some additional small issue: this is odd spaces in "optional arguments". Do you know how to separate "Commands" and "optional arguments" for do not have spaces in "optional arguments" and have spaces in "Commands" since these are different essences?

推荐答案

宽度也需要增加

试试:

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

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

As my earlier thoughts (below) show, the formatting considers overall width as well as the max_position value.

(之前)

在我有限的测试中,您的格式化程序子类似乎有效.但我没有突破极限.

In my limited testing, your formatter subclass seems to work. But I haven't pushed the limits.

您需要深入研究格式化程序代码.

You many need to dig more into the Formatter code.

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

For example there is a format_action method that actually uses the 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
    ...

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

Notice that it interacts with the width. Then it goes on to actually format the help lines and perform wrapping. So the actual implementation is not simple.

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

I'm not following your question about spaces. format_help commands the formatter to format a number of sections (including argument groups). The sections (usually) end with a couple of line feeds. Upon assembling them the formatter removes 'unnecessary' line feeds, leaving one space between groups. The subparser doesn't fit other categories, so I'd have to study the code to see exactly how it is handled.

您的 lambda 定义也适用.我以前从未见过它,我认为这不是开发人员的意图,但 Python 并不重要 - 如果它有效.

Your lambda definition works as well. I haven't seen it before, and I don't think it's what the developers intended, but Python that doesn't matter - if it works.

玩弄值和字符串,我发现 max_position 最多可达 56 个.然后它有点粘.但如果我也改变 width(默认来自 CONSOLE),我可以进一步增加 max_position.

Playing around with values and strings, I see that max_position up to about 56 works. Then it sort of sticks. But if I also change width (default is from CONSOLE), I can increase max_position further.

我用一个很长的 parser 参数来测试这个.添加

I was testing this with a long parser argument. Adding

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

所以 max_help_position 在常规解析器格式中确实有效.但是由于某种原因,当只有子解析器名称很长时,它不会.该部分需要一些特殊的格式.它是缩进的,并且子解析器名称不是实际操作(参数),而是选择 subparsers 参数.我会更详细地研究它.

So max_help_position does work in regular parser formatting. But for some reason, when only the subparser names are long, it does not. That section requires some special formatting. It is indented, and the subparser names are not real actions (arguments) but rather choices the subparsers argument. I'll have study it in more detail.

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

The subparser name string is indented 2 extra characters (compared to other arguments). The code that collects self._action_max_length does not take this into account. Hence if the subparser name is the longest string, this max_length will end up 2 spaces short. Compare actual v desired:

long_long_long_long_long_long_long
                                  - jksljdalkjda
long_long_long_long_long_long_long  - jksljdalkjda

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

(Formatting is done in 2 steps; once to calculate values like this _action_max_length, and a 2nd time to produce the actual output).

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

Subparsers are formatted with a recursive call to _format_action, so I'm not optimistic about an easy fix.

更正的格式化程序

这是一个打补丁的格式化程序,它正确地解释了子操作(子解析器)的缩进.当一个参数(动作)被添加到 Formatter 时,这个函数会计算它的调用字符串的宽度,并调整 self._max_action_length.后者用于缩进帮助字符串.

Here's a patched Formatter that correctly accounts for the indenting of subactions (sub parsers). When an argument (action) is added to the Formatter, this function figures how wide its invocation strings are, and adjusts self._max_action_length. This is used latter to indent the help strings.

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])

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

An example of its use (without going real wide):

# 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

这篇关于max_help_position 在 python argparse 库中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆