【问题标题】:Python: Prettier argparse outputPython:更漂亮的 argparse 输出
【发布时间】:2016-02-14 14:53:06
【问题描述】:

我正在编写一个 Django 管理命令。当我尝试在省略所需参数的情况下运行它时,我得到以下输出:

$ ./manage.py generatebooktemplate 
usage: manage.py generatebooktemplate [-h] [--version] [-v {0,1,2,3}]
                                      [--settings SETTINGS]
                                      [--pythonpath PYTHONPATH] [--traceback]
                                      [--no-color] --name NAME --width WIDTH
                                      --height HEIGHT --h-outer-margin
                                      H_OUTER_MARGIN --h-inner-margin
                                      H_INNER_MARGIN --v-outer-margin
                                      V_OUTER_MARGIN --v-inner-margin
                                      V_INNER_MARGIN --cols COLS --rows ROWS
manage.py generatebooktemplate: error: argument --name is required

看看在某些地方 arg 名称如何出现在一行中,而占位符出现在下一行。有点难读。有什么办法解决这个问题?

注意:我不是指我提供 argparse 的帮助文本,这个问题与基于我定义的参数自动生成的帮助输出有关。

【问题讨论】:

标签: python argparse


【解决方案1】:

帮助输出由HelpFormatter(默认)或formatter_class参数指定的子类格式化。正式地,只有类的名称被认为是公共 API 的一部分;它们的实际工作方式是实现细节,不能保证保持不变。

HelpFormatter.__init__ 接受 width 参数,但似乎没有办法实际将值传递给它。您甚至无法修补实例,因为只存储了类并且它在不同的地方按需实例化。您可以尝试以下方法:

from functools import partial

p = ArgumentParser(formatter_class=partial(HelpFormatter, width=200))

强制更长的宽度。扫描代码,我没有看到 formatter_class 值被用作实例化它的可调用对象之外的任何地方。

作为替代方案,您可以定义ArgumentParser 的子类并覆盖其_get_formatter 方法,该方法目前仅使用单个参数实例化格式化程序。您的子类可以提供一种将参数传递给该调用的方法。

【讨论】:

    【解决方案2】:

    问题在于格式化usage 行的函数中的换行。

    HelpFormatter._format_usage
    

    不幸的是,这个函数又长又脆弱。它使用HelpFormatter._format_actions_usage 来格式化用法。考虑到_width 和当前indent,函数的其余部分将此文本拆分为行。它在空格上拆分,无论它们是在参数之间还是在标志和元变量之间。

    部分问题是缩进很大:

    usage: manage.py generatebooktemplate 
    

    generatebooktemplate 可能是子命令(子解析器)名称。

    另一个问题是文本宽度。据说这是可控的,但正如另一个需要一些技巧的答案所示。

    您可以编写自定义usage 行,但我认为这不能让您控制换行符。 RawHelpRawDescription 帮助类不适用,因为 usage 使用自己的行格式化程序。

    您可以使用参数metavar 参数,缩短用法中的名称。您还可以使用这些参数的定义顺序。

    在您的测试代码中,使用

    parser.format_usage()
    parser.print_usage()
    

    查看使用行而不必产生错误。

    最后,您可以继承 HelpFormatter 并重写 _format_usage 以满足您的需求。如果你不使用任何互斥组会更容易。

    【讨论】:

      【解决方案3】:

      您可以使用 formatter argparse 类 定义您自己的帮助文本格式。

      另见Python argparse: How to insert newline in the help text?

      【讨论】:

      • 这里的问题是usage的格式,而不是descriptionhelp的其他部分。
      猜你喜欢
      • 1970-01-01
      • 2014-12-13
      • 2014-08-16
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 2020-11-21
      相关资源
      最近更新 更多