python argparse 在描述后打印使用文本
有没有办法在使用python argparse时,在描述文本后面打印使用说明文本?我已经让命令行的argparse正常工作了,但我想在使用信息之前打印版本信息。
编辑:
version: 1.0
usage: blahcmd [-h] [-help]
some lovely help
4 个回答
这个解决方案可以在解析过程中捕获所有的标准输出和错误输出,具体可以参考这个链接。
当没有输入或者输入“-h,--help”时,它会打印出自定义的命令,这个灵感来源于这个链接和这个链接。
try:
_out = io.StringIO()
_err = io.StringIO()
with redirect_stdout(_out):
with redirect_stderr(_err):
ARG = parser.parse_args(sys.argv[1:] or ['--help'])
except SystemExit as err:
print("This program does something awesome but you got it wrong.")
#possibly parser.print_help()
sys.stderr.write(_err.getvalue())
sys.stdout.write(_out.getvalue())
sys.exit(err.code)
一个简单的解决办法是把版本信息加到你的使用说明里。这不是最完美的办法(注意多了一个'usage'的文字),但算是一个开始。
In [64]: parser=argparse.ArgumentParser(description='description')
# 'usage' parameter just sets the 'usage' attribute
In [67]: parser.usage='version 1.0.1\n'+parser.format_usage()
In [68]: parser.print_help()
usage: version 1.0.1
usage: ipython [-h]
description
optional arguments:
-h, --help show this help message and exit
在help
中的内容顺序是由ArgumentParser.format_help
这个方法决定的(引用自argparse.py
文件):
def format_help(self):
formatter = self._get_formatter()
# usage
formatter.add_usage(self.usage, self._actions,
self._mutually_exclusive_groups)
# description
formatter.add_text(self.description)
# positionals, optionals and user-defined groups
for action_group in self._action_groups:
formatter.start_section(action_group.title)
formatter.add_text(action_group.description)
formatter.add_arguments(action_group._group_actions)
formatter.end_section()
# epilog
formatter.add_text(self.epilog)
# determine help from format above
return formatter.format_help()
我可以想象写一个自定义的方法来添加你的版本信息,比如:
def format_help(self):
formatter = self._get_formatter()
# version info
formatter.add_text('version 1.0.1')
# usage
formatter.add_usage(self.usage, self._actions,
self._mutually_exclusive_groups)
...
在ipython
中,这个函数可以正常工作:
In [74]: def format_help(parser):
formatter=parser._get_formatter()
formatter.add_text('version 1.0.1')
formatter.add_usage(parser.usage, parser._actions, parser._mutually_exclusive_groups)
formatter.add_text(parser.description)
return formatter.format_help()
In [75]: print format_help(parser)
version 1.0.1
usage: ipython [-h]
description
这里有个不太优雅的解决办法(可以看看我在原问题下的评论):
你可以自己定义一个 HelpFormatter
的子类,然后在解析器中使用 formatter_class
选项来传递这个子类。这个子类可能需要重写 _format_usage
这个方法。不过,这种做法并不是特别推荐,因为定义自己格式化类的接口并没有公开。
from argparse import ArgumentParser, HelpFormatter
from gettext import gettext as _
class VersionedHelp(HelpFormatter):
def _format_usage(self, usage, actions, groups, prefix=None):
if prefix is None:
prefix = _('Version: x.y\n\nusage: ')
return HelpFormatter._format_usage(self, usage, actions, groups, prefix)
p = ArgumentParser(formatter_class=VersionedHelp)
p.parse_args()
argparse
模块没有提供添加“前言”的选项。当你显示帮助信息时,它总是以usage:
开头。你能做的最好的事情就是在创建ArgumentParser
时,使用usage
参数来自定义使用说明文本,添加版本号:
import argparse
parser = argparse.ArgumentParser(usage='Any text you want\n')
请注意,帮助信息仍然会以usage:
开头。
一个不太优雅的解决办法是让usage
信息以\r
开头:
>>> import argparse
>>> usage = '\r{}\nusage: %(prog)s etc.'.format('Version a b'.ljust(len('usage:')))
>>> parser = argparse.ArgumentParser(usage=usage)
>>> parser.parse_args(['-h'])
Version a b
usage: etc.
optional arguments:
-h, --help show this help message and exit
我觉得这种使用\r
的方法可能不太通用。可能有些终端不支持这个技巧。我已经用ljust
调整了版本字符串,确保当这个技巧有效时,整个usage:
字符串会消失,这样你就不会看到像v1.2e:
这样的短版本字符串。
注意:你现在必须手动创建完整的usage
文本。