Python argparse.RawTextHelpFormatter 换行

Python argparse.RawTextHelpFormatter with line wrap

在我的参数解析代码中,我需要使用 argparse.RawTextHelpFormatter,但我也希望以与默认格式化程序相同的方式自动以固定宽度换行。

有什么优雅的方法可以结合这两种行为吗?

编写自定义 RawTextHelpFormatter

您可以自己编写 RawTextHelpFormatterRawTextHelpFormatterArgumentDefaultsHelpFormatter 仅在方法 _fill_text_split_lines 上有所不同,因此只需覆盖 _spilt_lines_ 方法即可使用换行修复此问题。

import argparse
import textwrap as _textwrap

class LineWrapRawTextHelpFormatter(argparse.RawDescriptionHelpFormatter):
    def _split_lines(self, text, width):
        text = self._whitespace_matcher.sub(' ', text).strip()
        return _textwrap.wrap(text, width)


parser = argparse.ArgumentParser(
    prog='PROG',
    formatter_class=LineWrapRawTextHelpFormatter)
parser.add_argument('--foo', type=int, default=42, help="FOO! Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an u")
parser.add_argument('bar', nargs='*', default=[1, 2, 3], help="BAR! FOO! Lorem Ipsum is simply dummy text of the printing and typesetting industry.")
parser.print_help()

输出

usage: PROG [-h] [--foo FOO] [bar [bar ...]]

positional arguments:
  bar         BAR! FOO! Lorem Ipsum is simply dummy text of the printing and
              typesetting industry.

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   FOO! Lorem Ipsum is simply dummy text of the printing and
              typesetting industry. Lorem Ipsum has been the industry's
              standard dummy text ever since the 1500s, when an u

如您所见,该行已自动换行。如果要调整宽度,可以在 _spilit_lines 方法中将宽度硬编码在 _textwrap.wrap(text, width) 处(它只是以 FOO! Lorem 开头的部分的宽度)或使用 _os.environ['COLUMNS'] (这是完整帮助文本的宽度)。

包含列的代码=40

import os
os.environ['COLUMNS'] = "40"

输出

usage: PROG [-h] [--foo FOO]
            [bar [bar ...]]

positional arguments:
  bar         BAR! FOO! Lorem Ipsum is
              simply dummy text of the
              printing and typesetting
              industry.

optional arguments:
  -h, --help  show this help message
              and exit
  --foo FOO   FOO! Lorem Ipsum is
              simply dummy text of the
              printing and typesetting
              industry. Lorem Ipsum
              has been the industry's
              standard dummy text ever
              since the 1500s, when an
              u

硬编码 40

def _split_lines(self, text, width):
    text = self._whitespace_matcher.sub(' ', text).strip()
    return _textwrap.wrap(text, 40)

输出

usage: PROG [-h] [--foo FOO] [bar [bar ...]]

positional arguments:
  bar         BAR! FOO! Lorem Ipsum is simply dummy
              text of the printing and typesetting
              industry.

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   FOO! Lorem Ipsum is simply dummy text of
              the printing and typesetting industry.
              Lorem Ipsum has been the industry's
              standard dummy text ever since the

PreserveWhiteSpaces,例如要点

如果你想保留换行符前面的空格,我只写了一个 PreserveWhiteSpaceWrapRawTextHelpFormatter。

import argparse
import textwrap as _textwrap
import re

class PreserveWhiteSpaceWrapRawTextHelpFormatter(argparse.RawDescriptionHelpFormatter):
    def __add_whitespace(self, idx, iWSpace, text):
        if idx is 0:
            return text
        return (" " * iWSpace) + text

    def _split_lines(self, text, width):
        textRows = text.splitlines()
        for idx,line in enumerate(textRows):
            search = re.search('\s*[0-9\-]{0,}\.?\s*', line)
            if line.strip() is "":
                textRows[idx] = " "
            elif search:
                lWSpace = search.end()
                lines = [self.__add_whitespace(i,lWSpace,x) for i,x in enumerate(_textwrap.wrap(line, width))]
                textRows[idx] = lines

        return [item for sublist in textRows for item in sublist]

它只是看看文本文本的缩进是什么,并为每个 _textwrap.warp 行添加这个。使用此参数调用。

parser = argparse.ArgumentParser(
    prog='PROG',
    formatter_class=PreserveWhiteSpaceWrapRawTextHelpFormatter)
parser.add_argument('--foo', type=int, default=42, help="""Just Normal Bullet Point with Some Enter in there

    1. Lorem Ipsum has been the industry's standard dummy text ever since
    2. the 1500s, when an u
    3. Lorem Ipsum is simply dummy text of the printing and typesetting industry

Some other Bullet POint

    - Ipsum is simply dummy text of the printing and typesetting industry
    - Ipsum is simply dummy text of the printing and typesetting industry

And No BulletPoint
    Ipsum is simply dummy text of the printing and typesetting industry
    Ipsum is simply dummy text of the printing and typesetting industry
    """)
parser.add_argument('bar', nargs='*', default=[1, 2, 3], help="BAR! FOO! Lorem Ipsum is simply dummy text of the printing and typesetting industry.")
parser.print_help()

输出

usage: PROG [-h] [--foo FOO] [bar [bar ...]]

positional arguments:
  bar         BAR! FOO! Lorem Ipsum is simply dummy text of the printing and
              typesetting industry.

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   Just Normal Bullet Point with Some Enter in there

                  1. Lorem Ipsum has been the industry's standard dummy text
                     ever since
                  2. the 1500s, when an u
                  3. Lorem Ipsum is simply dummy text of the printing and
                     typesetting industry

              Some other Bullet POint

                  - Ipsum is simply dummy text of the printing and typesetting
                    industry
                  - Ipsum is simply dummy text of the printing and typesetting
                    industry

              And No BulletPoint and no Enter
                  Ipsum is simply dummy text of the printing and typesetting
                  industry
                  Ipsum is simply dummy text of the printing and typesetting
                  industry