【问题标题】:ArgumentParser epilog and description formatting in conjunction with ArgumentDefaultsHelpFormatterArgumentParser 结语和描述格式与 ArgumentDefaultsHelpFormatter 结合使用
【发布时间】:2013-08-28 01:23:54
【问题描述】:

我使用argparse 接收命令行输入并生成帮助文本。我想使用ArgumentDefaultsHelpFormatter 作为formatter_class,但这会阻止我也使用RawDescriptionHelpFormatter,这将允许我在我的描述或结语中添加自定义格式。

除了自己编写代码来为默认值生成文本之外,是否还有一种明智的方法来实现这一点?根据 argparse 文档,ArgumentParser 的所有内部结构都被视为实现细节,而不是公共 API,因此子类化不是一个有吸引力的选择。

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    我刚刚尝试了一种多重继承方法,它确实有效:

    class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
        pass
    
    parser = argparse.ArgumentParser(description='test\ntest\ntest.',
                                     epilog='test\ntest\ntest.',
                                     formatter_class=CustomFormatter)
    

    如果这些类的内部发生变化,这可能会中断。

    【讨论】:

    • 以这种方式子类化不依赖于内部。如果多重继承现在工作,它应该在所有未来的变化。正如我的解决方案所示,这两个类正在改变不同的格式化方法。
    • 另一个使用多重继承的例子:stackoverflow.com/questions/23567393/…
    • @hpaulj 格式化程序方法不是公共 API 的一部分。来自argparse.HelpFormatter 的文档字符串:Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.。这两个类都可以完全重写。
    • 转念一想,argparse 的作者提到这是this issue (2011) 中推荐的解决方案。我想这使得这种方法在未来的版本中得到非官方的支持。
    • 所有这意味着在遥远的将来argparse 开发人员可能会重写HelpFormatter 类,并破坏您的自定义。然而,我对这个过程的经验是,变化来得很慢,并且适当考虑(可能过度)向后兼容。
    【解决方案2】:

    我不明白为什么继承 HelpFormatter 应该是一个问题。这不会影响ArgumentParser 的内部结构。该文档包含自定义 ActionType 类(或函数)的示例。如果需要,我将 'there are four such classes' 行作为编写自己的 HelpFormatter 的邀请。

    提供的HelpFormatter 子类进行了非常简单的更改,只更改了一个函数。因此可以轻松复制或更改它们。

    RawDescription 只是变化:

    def _fill_text(self, text, width, indent):
        return ''.join(indent + line for line in text.splitlines(keepends=True))
    

    理论上可以在不更改 API 的情况下更改它,但不太可能。

    默认格式化程序只是更改:

    def _get_help_string(self, action):
        help = action.help
        if '%(default)' not in action.help:
            if action.default is not SUPPRESS:
                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
                if action.option_strings or action.nargs in defaulting_nargs:
                    help += ' (default: %(default)s)'
        return help
    

    只需在所有参数帮助行中包含 %(default)s 即可获得相同的效果。与Raw 子类相比,这只是一个便利类。它无法让您更好地控制格式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-09
      • 1970-01-01
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 2021-06-03
      • 2016-01-05
      相关资源
      最近更新 更多