我在Python 2.7中使用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 = 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

如何在帮助文本中插入换行?


当前回答

迟到了12年,但我也需要这个。

OP要求在帮助(不是描述)中的新行,因此这里的解决方案实际上并不完全有效,因为如果一行比屏幕宽度长,那么它在包装时失去缩进(被包装到列1而不是保留帮助文本的缩进),这看起来真的很难看,或空行被吞噬,这是我不想要的,因为我有时需要长帮助文本中的空行。

工作方案如下:

import textwrap

class CustomHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
    def _split_lines(self, text, width):
        wrapper = textwrap.TextWrapper(width=width)
        lines = []
        for line in text.splitlines():
            if len(line) > width:
                lines.extend(wrapper.wrap(line))
            else:
                lines.append(line)
        return lines

parser = argparse.ArgumentParser(formatter_class=CustomArgumentFormatter)

其他回答

使用RawTextHelpFormatter获取新行并处理缩进的另一种简单方法是

import argparse

parser = argparse.ArgumentParser(
    description='test', formatter_class=argparse.RawTextHelpFormatter)

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

输出为

$ python2 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

我来这里寻找方法来获得ArgumentDefaultsHelpFormatter的行为,但与换行符和制表符荣誉。特洛伊的代码让我接近了,但最终的结果更简单一些:

class CustomArgumentFormatter(argparse.ArgumentDefaultsHelpFormatter):
    """
    Formats help text to honor newlines and tabs (and show default values).
    """

    # Match multiples of regular spaces only.
    _SPACE_MATCHER = re.compile(r' +', re.ASCII)

    def _split_lines(self, text, width):
        new_text = []
        for line in text.splitlines():
          # For each newline in the help message, replace any multiples of
          # whitespaces (due to indentation in source code) with one space.
          line = self._SPACE_MATCHER.sub(' ', line).rstrip()
          # Fit the line length to the console width
          new_text.extend(textwrap.wrap(line, width))
        return new_text

然后换行符和制表符将按预期出现:

parser = argparse.ArgumentParser(formatter_class=CustomArgumentFormatter)

parser.add_argument(
    '--ethernet_config', type=str, required=False, default=None,
    help='Path to a text file that specifies Ethernet network IP settings \
      to use on the board. For example: \
      \n\t ip=192.0.2.100 \
      \n\t subnet_mask=255.255.255.0 \
      \n\t gateway=192.0.2.1')

迟到了12年,但我也需要这个。

OP要求在帮助(不是描述)中的新行,因此这里的解决方案实际上并不完全有效,因为如果一行比屏幕宽度长,那么它在包装时失去缩进(被包装到列1而不是保留帮助文本的缩进),这看起来真的很难看,或空行被吞噬,这是我不想要的,因为我有时需要长帮助文本中的空行。

工作方案如下:

import textwrap

class CustomHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
    def _split_lines(self, text, width):
        wrapper = textwrap.TextWrapper(width=width)
        lines = []
        for line in text.splitlines():
            if len(line) > width:
                lines.extend(wrapper.wrap(line))
            else:
                lines.append(line)
        return lines

parser = argparse.ArgumentParser(formatter_class=CustomArgumentFormatter)

如果存在默认值,以下python 3格式化器将追加默认值并保留行长。

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

尝试使用RawTextHelpFormatter来保存所有的格式:

from argparse import RawTextHelpFormatter
parser = ArgumentParser(description='test', formatter_class=RawTextHelpFormatter)

它类似于RawDescriptionHelpFormatter,但不是只应用于描述和epilog, RawTextHelpFormatter也应用于所有帮助文本(包括参数)。