从argparse获取版本字符串

时间:2014-11-05 12:49:34

标签: python python-2.7 argparse

我试图找回我在argparse中定义的版本字符串以用于日志记录。 我使用的典型设置如下:

__version__ = "0.1"
parser = argparse.ArgumentParser()
parser.add_argument('--version', '-V', action='version', version="%(prog)s " + __version__)
args = parser.parse_args()

当我打印parser.version()parser.print_version()parser.format_version()时,我得到None。一种解决方案是调用parser.parse_args(['-V']),但这也会终止程序的执行。我知道我可以重新创建字符串并将其传递给记录器,但我认为必须有一种方法可以从argparse获取此字符串。我使用的是python v2.7.5和argparse v1.1。

3 个答案:

答案 0 :(得分:2)

没有 public API来获取该信息。不推荐使用parser.version属性。您必须找到argparse._VersionAction对象并从那里获取它:

version_action = next((action for action in parser._get_optional_actions()
                       if isinstance(action, argparse._VersionAction)), None)
print version_action.version if version_action else 'unknown'

这使用了可能会发生变化的私有方法,您获得的只是argparse完全相同的字符串

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--version', '-V', action='version', version="%(prog)s " + __version__)
_VersionAction(option_strings=['--version', '-V'], dest='version', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help="show program's version number and exit", metavar=None)
>>> version_action = next((action for action in parser._get_optional_actions() if isinstance(action, argparse._VersionAction)), None)
>>> print version_action.version if version_action else 'unknown'
%(prog)s 0.1

将该值存储在其他位置也更容易,然后将其传递给argparse 直接使用该值。

答案 1 :(得分:0)

不,一定不能有办法从argparse获取它。为什么会这样?你告诉argparse版本号是什么,而不是相反。 而且你不需要重新创造"字符串。只需创建一次,然后将其传递给argparse。

我确定它在某种程度上是可用的,来自argparse的一些属性,但从那里获取它确实毫无意义,并要求你使用argparse内部,这可能在将来发生变化。

答案 2 :(得分:0)

format_version(以及使用print_version的{​​{1}})会显示format_version属性,您可以使用parser.version参数设置该属性。但正如Martijn写的那样,展示版本的方法已被删除。你会收到一条警告信息。

version参数采用不同的路径。它有自己的action='version'参数(但使用version作为备份)。当由parser.version参数字符串触发时,它会显示该版本信息并调用系统退出。

您仍然可以调用-v,并使用try块避免系统退出:

-v

这对于测试很方便,但不是你想要的东西。此外,它还会捕获其他出口,如帮助和错误。

与任何参数一样,您可以保存指向Action的链接,并显示,使用甚至修改其属性。

try:
    p.parse_args(['-V'])
except SystemExit:
    pass

在功能上,这与Martijn搜索version_action = parser.add_argument('--version', '-V', action='version', version="%(prog)s " + __version__) print version_action print version_action.version assert isinstance(version_action, argparse._VersionAction) 相同,但更简单。

您可以在不使用系统退出的情况下复制parser._get_optional_actions()的操作:

_VersionAction.__call__

虽然在这种情况下它只是填写def foo(action, parser): formatter = parser._get_formatter() formatter.add_text(action.version) return formatter.format_help() foo(version_action, parser) 字符串。

http://bugs.python.org/issue9399'为argparse提供'打印'操作',讨论添加'print'或'write'操作类型。它的行为类似于'版本',但没有系统退出,可能更多地控制格式化和打印目的地。