使用自定义formatter_class在Python 2.7.5 argparse.add_argument()中出现神秘故障

时间:2014-07-22 00:12:03

标签: python argparse

我正在尝试编写一个HelpFormatter的子类来与argparse一起使用。格式化程序很简单;将它作为子类集成不是。在Anthon的回答中,我在stackoverflow.com/questions/3853722/找到了一个非常有用的例子。

在Mac OS X 10.9.4上使用Python 2.7.5。当我尝试子类化HelpFormatter时,我不断得到:

./testBlankLineHelpFormatter.py -q
******* LOADING MY CLASS
Instantiating argparse.ArgumentParser
Traceback (most recent call last):
  File "./testBlankLineHelpFormatter.py", line 15, in <module>
    formatter_class=BlankLineHelpFormatter
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1600, in __init__
    help=_('show this help message and exit'))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1293, in add_argument
    raise ValueError("length of metavar tuple does not match nargs")
ValueError: length of metavar tuple does not match nargs

* 请注意,错误是在实例化我的子类时,当标准类尝试添加“--help”项时 - 它永远不会到达我的任何add_argument()调用。我将我的子类调整到这个,但它仍然失败:

class BlankLineHelpFormatter(argparse.HelpFormatter):
    """
A formatter for argparse that just respects blank lines (as in, doesn't
wrap across them).

See also: http://bugs.python.org/issue12806

"""

    sys.stderr.write("******* LOADING MY CLASS\n")

    def __init__(self, *args, **kw):
        sys.stderr.write("******* IN MY INIT\n")
        super(BlankLineHelpFormatter, self).__init__(*args, **kw)

* 我正在使用一个驱动程序来运行它我也已经减少了,对此:

#!/usr/bin/python
#
from __future__ import print_function
import argparse
import BlankLineHelpFormatter

print("Instantiating argparse.ArgumentParser")

parser = argparse.ArgumentParser(
    description="""
This work is licensed under a Creative Commons
Attribution-Share Alike 3.0 Unported License. For further information on
this license, look it up.
    """,
    formatter_class=BlankLineHelpFormatter
)

print("Adding --quiet\n")
parser.add_argument(
    "--quiet", "-q",      action='store_true',
    help='Suppress most messages.')

print("Instantiated, now trying parse_args")
args = parser.parse_args()

print("Back.")

print("You might want to try '-h'...")

sys.exit(0)

我查看了argparse库源代码,即使在上下文中,问题对我也没有意义。这是一个阻止子类化HelpFormatter的错误,还是我在剩余的代码中遗漏了一些东西?

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您正在传递BlankLineHelpFormatter模块作为格式化程序,而不是BlankLineHelpFormatter类。错误消息来自this part of the argparse source

        # raise an error if the metavar does not match the type
        if hasattr(self, "_get_formatter"):
            try:
                self._get_formatter()._format_args(action, None)
            except TypeError:
                raise ValueError("length of metavar tuple does not match nargs")

_get_formatter()尝试调用模块来创建格式化程序,然后将生成的TypeError误解为其他内容。

修复应该是指定

formatter_class=BlankLineHelpFormatter.BlankLineHelpFormatter

答案 1 :(得分:0)

如果有兴趣,argparse的格式化工具现在正在http://derose.net/steve/utilities/PY/MarkupHelpFormatter.py上运行(CCLI Attribution-Share-similar许可证)。再次感谢@ user2357112提前帮助!

ANSI终端的这些类格式。没有高度抛光(例如,自动编号未完成),但您可能会发现它们很有帮助。

&#34; MarkupHelpFormatter&#34;支持大部分mediaWiki,MarkDown和POD语法(甚至是混合):

import MarkupHelpFormatter
MarkupHelpFormatter.InputOptions["mediawiki"] = True
parser = argparse.ArgumentParser(
    description="""...your text, with mediawiki markup...""",
    epilog='...',
    formatter_class=MarkupHelpFormatter.MarkupHelpFormatter
)

&#34; ParagraphHelpFormatter&#34;只是包装文本,如默认的argparse格式化程序,除了它尊重空行。错误报告,修复,增强等欢迎。