max_help_position 在 python argparse 库中不起作用 [英] max_help_position is not works in python argparse library
问题描述
各位同事,我有代码(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屋!