2016-02-12 64 views
1

我在写一个Django管理命令。当我尝试用省略需要ARGS运行它,我得到这个输出:Python:漂亮的argparse输出

$ ./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的帮助文本,这个问题属于基于我定义的参数的自动生成的帮助输出。

+0

[Python argparse:如何在帮助文本中插入换行符?](http://stackoverflow.com/questions/3853722/python-argparse-how-to-insert-newline-in-the-help -text) – jofel

+0

此输出是由argparse自动生成的,另一个问题与手动指定的帮助文本中的换行符有关。 –

回答

0

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

HelpFormatter.__init__需要width参数,但似乎没有办法将值实际传递给它。你甚至不能修补实例,因为只有类被存储并且在各个地方按需实例化。您可以尝试以下操作:

from functools import partial 

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

强制更长的宽度。扫描代码时,我没有看到formatter_class值被用作可调用实例化的地方。

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

1

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

HelpFormatter._format_usage 

不幸的是,这个功能很长很脆弱。它使用HelpFormatter._format_actions_usage来格式化使用情况。该函数的其余部分将这些文本分成几行,并考虑到_width和当前的indent。它在空间上分裂,不管它们是在参数之间还是在标志和metavar之间。你的问题的

部分是大缩进:

usage: manage.py generatebooktemplate 

generatebooktemplate可能是一个子(子分析器)的名字。

另一个问题是文字宽度。据说这是可控的,但如另一个需要一些欺骗的答案所示。

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

您可以使用参数metavar参数进行游戏,缩短使用中的名称。您也可以玩这些参数定义的顺序。

在你的测试代码,使用

parser.format_usage() 
parser.print_usage() 

看到使用线,而不必产生一个错误。

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