Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在argparse帮助文本上插入换行符?_Python_Argparse - Fatal编程技术网

Python 如何在argparse帮助文本上插入换行符?

Python 如何在argparse帮助文本上插入换行符?,python,argparse,Python,Argparse,我正在使用解析输入选项。我的选择之一是多项选择。我想在它的帮助文本中列出一个列表,例如 from argparse import ArgumentParser parser = ArgumentParser(description='test') parser.add_argument('-g', choices=['a', 'b', 'g', 'd', 'e'], default='a', help="Some option, where\n" " a = alp

我正在使用解析输入选项。我的选择之一是多项选择。我想在它的帮助文本中列出一个列表,例如

from argparse import ArgumentParser

parser = ArgumentParser(description='test')

parser.add_argument('-g', choices=['a', 'b', 'g', 'd', 'e'], default='a',
    help="Some option, where\n"
         " a = alpha\n"
         " b = beta\n"
         " g = gamma\n"
         " d = delta\n"
         " e = epsilon")

parser.parse_args()
但是,
argparse
会去除所有换行符和连续空格。结果看起来像

~/Downloads:52$ python2.7 x.py -h usage: x.py [-h] [-g {a,b,g,d,e}] test optional arguments: -h, --help show this help message and exit -g {a,b,g,d,e} Some option, where a = alpha b = beta g = gamma d = delta e = epsilon ~/下载:52$python2.7x.py-h 用法:x.py[-h][g{a,b,g,d,e}] 测试 可选参数: -h、 --帮助显示此帮助消息并退出 -g{a,b,g,d,e}一些选项,其中a=alpha b=beta g=gamma d=delta e =ε 如何在帮助文本中插入换行?

尝试使用:


如果只想覆盖一个选项,则不应使用
RawTextHelpFormatter
。相反,将
帮助格式化程序子类化,并为应该“原始”处理的选项提供一个特殊的介绍(我使用
“R|rest of help”
):

并使用它:

from argparse import ArgumentParser

parser = ArgumentParser(description='test', formatter_class=SmartFormatter)

parser.add_argument('-g', choices=['a', 'b', 'g', 'd', 'e'], default='a',
    help="R|Some option, where\n"
         " a = alpha\n"
         " b = beta\n"
         " g = gamma\n"
         " d = delta\n"
         " e = epsilon")

parser.parse_args()
.add_argument()
的任何其他调用,如果帮助不是以
R |
开头,将按正常方式包装

这是我的一部分。完整的SmartFormatter还支持添加 默认设置为所有选项,以及实用程序描述的原始输入。完整版本 有自己的
\u split\u line
方法,以便保留对版本字符串等所做的任何格式化:

parser.add_argument('--version', '-v', action="version",
                    version="version...\n   42!")
我也遇到过类似的问题(Python 2.7.6)。我已尝试使用
RawTextHelpFormatter
描述部分分解为几行:

parser = ArgumentParser(description="""First paragraph 

                                       Second paragraph

                                       Third paragraph""",  
                                       usage='%(prog)s [OPTIONS]', 
                                       formatter_class=RawTextHelpFormatter)

options = parser.parse_args()
得到:

usage: play-with-argparse.py [OPTIONS] First paragraph Second paragraph Third paragraph optional arguments: -h, --help show this help message and exit 与来自模块的原始源代码进行比较:

在原始代码中,整个描述被包装起来。在上面的自定义格式化程序中,整个文本被分成几个块,每个块都独立格式化

因此,借助自定义格式化程序:

parser = ArgumentParser(description= """First paragraph 
                                        |n                              
                                        Second paragraph
                                        |n
                                        Third paragraph""",  
                usage='%(prog)s [OPTIONS]',
                formatter_class=MultilineFormatter)

options = parser.parse_args()
my_arg_parser = ArgumentParser(formatter_class=CustomArgumentFormatter)
# ... add your arguments ...
print(my_arg_parser.format_help())
输出为:

usage: play-with-argparse.py [OPTIONS] First paragraph Second paragraph Third paragraph optional arguments: -h, --help show this help message and exit 用法:play-with-argparse.py[选项] 第一段 第二段 第三段 可选参数: -h、 --帮助显示此帮助消息并退出
另一个简单的方法是包含

比如说,

import argparse, textwrap
parser = argparse.ArgumentParser(description='some information',
        usage='use "python %(prog)s --help" for more information',
        formatter_class=argparse.RawTextHelpFormatter)

parser.add_argument('--argument', default=somedefault, type=sometype,
        help= textwrap.dedent('''\
        First line
        Second line
        More lines ... '''))
这样,我们可以避免每个输出行前面的长空空间

usage: use "python your_python_program.py --help" for more information

Prepare input file

optional arguments:
-h, --help            show this help message and exit
--argument ARGUMENT
                      First line
                      Second line
                      More lines ...

我希望在描述文本中既有手动换行,也有自动换行;但是这里的建议对我都不起作用,所以我最终修改了答案中给出的SmartFormatter类;尽管argparse方法名不是公共API存在问题,但以下是我所拥有的(作为一个名为
test.py
的文件):

这是2.7和3.4中的工作原理:

$python test.py-h
用法:test.py[-h]
布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉布拉
.诸如此类
废话废话废话废话废话废话废话废话废话废话废话;废话
废话废话,废话废话:
废话废话废话废话废话废话
可选参数:
-h、 --帮助显示此帮助消息并退出

从上面描述的SmartFomatter开始,我以该解决方案结束:

class SmartFormatter(argparse.HelpFormatter):
    '''
         Custom Help Formatter used to split help text when '\n' was 
         inserted in it.
    '''

    def _split_lines(self, text, width):
        r = []
        for t in text.splitlines(): r.extend(argparse.HelpFormatter._split_lines(self, t, width))
        return r
请注意,奇怪的是,传递给顶级解析器的formatter_类参数不是由子解析器继承的,必须为每个创建的子解析器再次传递它。

对于这个问题,
argparse.RawTextHelpFormatter
对我很有帮助

现在,我想分享如何使用
argparse

我知道这可能和问题无关

但这些问题困扰了我一段时间

所以我想和大家分享我的经验,希望对大家有所帮助

我们开始吧

第三方模块 :更改文本颜色:
pip安装colorama

使ANSI转义字符序列(用于生成彩色终端文本和光标定位)在MS Windows下工作

例子

我承认我发现这是一次非常令人沮丧的经历,就像许多其他人一样,考虑到我看到发布的解决方案的数量,以及我在网上看到这一问题的次数。但我发现这些解决方案中的大多数对我来说太复杂了,我想和大家分享一下最简单的解决方案

下面是要演示的脚本:

#/usr/bin/python3
导入文本包装
从argparse导入ArgumentParser,HelpFormatter
类RawFormatter(帮助格式化程序):
定义填充文本(自身、文本、宽度、缩进):
返回“\n”.join([textwrap.fill(line,width)表示textwrap.indent(textwrap.dedent(text),indent.splitlines()]中的行)
程序描述符n=f''
FunkyTool v1.0
由时髦的家伙于2020年1月1日创作
版权所有2020。版权所有。
根据希波克拉底许可证2.1获得许可
https://firstdonoharm.dev/
按“原样”分发,无担保
或任何明示或暗示的条件。
用法:
'''
parser=ArgumentParser(description=program\u descriptor,formatter\u class=RawFormatter)
args=parser.parse_args()
下面是在
test.py
中的外观:

import argparse
from argparse import RawDescriptionHelpFormatter

# call with: python test.py -h

class SmartDescriptionFormatter(argparse.RawDescriptionHelpFormatter):
  #def _split_lines(self, text, width): # RawTextHelpFormatter, although function name might change depending on Python
  def _fill_text(self, text, width, indent): # RawDescriptionHelpFormatter, although function name might change depending on Python
    #print("splot",text)
    if text.startswith('R|'):
      paragraphs = text[2:].splitlines()
      rebroken = [argparse._textwrap.wrap(tpar, width) for tpar in paragraphs]
      #print(rebroken)
      rebrokenstr = []
      for tlinearr in rebroken:
        if (len(tlinearr) == 0):
          rebrokenstr.append("")
        else:
          for tlinepiece in tlinearr:
            rebrokenstr.append(tlinepiece)
      #print(rebrokenstr)
      return '\n'.join(rebrokenstr) #(argparse._textwrap.wrap(text[2:], width))
    # this is the RawTextHelpFormatter._split_lines
    #return argparse.HelpFormatter._split_lines(self, text, width)
    return argparse.RawDescriptionHelpFormatter._fill_text(self, text, width, indent)

parser = argparse.ArgumentParser(formatter_class=SmartDescriptionFormatter, description="""R|Blahbla bla blah blahh/blahbla (bla blah-blabla) a blahblah bl a blaha-blah .blah blah

Blah blah bla blahblah, bla blahblah blah blah bl blblah bl blahb; blah bl blah bl bl a blah, bla blahb bl:

  blah blahblah blah bl blah blahblah""")

options = parser.parse_args()
$ ./test.py --help
usage: test.py [-h]

FunkyTool v1.0

Created by the Funky Guy on January 1 2020
Copyright 2020. All rights reserved.

Licensed under The Hippocratic License 2.1
https://firstdonoharm.dev/

Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.

USAGE:

optional arguments:
  -h, --help  show this help message and exit
因此,原始描述中的所有基本格式都被整齐地保留下来,唉,我们不得不使用自定义格式设置程序,但它是一个单行程序。它可以更清楚地写为:

类RawFormatter(帮助格式化程序):
定义填充文本(自身、文本、宽度、缩进):
text=textwrap.dedent(text)#去掉困扰我们大多数人的原始python定义中的缩进。
text=textwrap.indent(text,indent)#应用任何请求的缩进。
text=text.splitlines()#列出行
text=[文本中的行的text Wrap.fill(行、宽度)]#换行
text=“\n”。连接(text)#再次连接行
返回文本

但是我更喜欢一行。

下面的Python3格式化程序在存在默认值的情况下附加默认值并保留行长度

from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, \ 
                     RawTextHelpFormatter
import textwrap

class CustomArgumentFormatter(ArgumentDefaultsHelpFormatter, RawTextHelpFormatter):
    """Formats argument help which maintains line length restrictions as well as appends default value if present."""

    def _split_lines(self, text, width):
        text = super()._split_lines(text, width)
        new_text = []

        # loop through all the lines to create the correct wrapping for each line segment.
        for line in text:
            if not line:
                # this would be a new line.
                new_text.append(line)
                continue

            # wrap the line's help segment which preserves new lines but ensures line lengths are
            # honored
            new_text.extend(textwrap.wrap(line, width))

        return new_text
然后使用新的格式化程序创建参数解析器:

parser = ArgumentParser(description= """First paragraph 
                                        |n                              
                                        Second paragraph
                                        |n
                                        Third paragraph""",  
                usage='%(prog)s [OPTIONS]',
                formatter_class=MultilineFormatter)

options = parser.parse_args()
my_arg_parser = ArgumentParser(formatter_class=CustomArgumentFormatter)
# ... add your arguments ...
print(my_arg_parser.format_help())

我没有带python 2.7,所以我可以测试我的想法。使用三重引号(“”)中的帮助文本如何。新台词能用这个生存吗?@pyfun
class FormatText:
    __slots__ = ['align_list']

    def __init__(self, align_list: list, autoreset=True):
        """
        USAGE::

            format_text = FormatText([(20, '<'), (60, '<')])
            red_dc = format_text.new_dc(fore_color=Fore.RED)
            print(red_dc(['column 1', 'column 2']))
            print(red_dc('good morning'))
        :param align_list:
        :param autoreset:
        """
        self.align_list = align_list
        colorama.init(autoreset=autoreset)

    def __call__(self, text_list: list):
        if len(text_list) != len(self.align_list):
            if isinstance(text_list, str):
                return text_list
            raise AttributeError
        return ' '.join(f'{txt:{flag}{int_align}}' for txt, (int_align, flag) in zip(text_list, self.align_list))

    def new_dc(self, fore_color: Fore = Fore.GREEN, back_color: Back = ""):  # DECORATOR
        """create a device context"""
        def wrap(msgs):
            return back_color + fore_color + self(msgs) + Fore.RESET
        return wrap
$ ./test.py --help
usage: test.py [-h]

FunkyTool v1.0

Created by the Funky Guy on January 1 2020
Copyright 2020. All rights reserved.

Licensed under The Hippocratic License 2.1
https://firstdonoharm.dev/

Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.

USAGE:

optional arguments:
  -h, --help  show this help message and exit
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, \ 
                     RawTextHelpFormatter
import textwrap

class CustomArgumentFormatter(ArgumentDefaultsHelpFormatter, RawTextHelpFormatter):
    """Formats argument help which maintains line length restrictions as well as appends default value if present."""

    def _split_lines(self, text, width):
        text = super()._split_lines(text, width)
        new_text = []

        # loop through all the lines to create the correct wrapping for each line segment.
        for line in text:
            if not line:
                # this would be a new line.
                new_text.append(line)
                continue

            # wrap the line's help segment which preserves new lines but ensures line lengths are
            # honored
            new_text.extend(textwrap.wrap(line, width))

        return new_text
my_arg_parser = ArgumentParser(formatter_class=CustomArgumentFormatter)
# ... add your arguments ...
print(my_arg_parser.format_help())