0

我正在尝试--set=X=Y使用 argparse、python 获取参数。第一种方法是:

parser.add_argument('--set', dest='d', metavar='book=from:to', action='append', type=str, required=True, help='...')

我必须自己拆分结果(X=Y),但这没关系。我的问题是关于--help从 argparse 生成的帮助消息 () 的语法。它使用可能更常见的语法--set X=Y导致:

--set book=from:to  ...

有没有办法让我改变这种行为,所以帮助看起来像:

--set=book=from:to  ...
4

2 回答 2

0

不,不是没有创建您自己的自定义类的子argparse.HelpFormatter()类。

这将需要替换该类的内部私有方法。当前实现使用这种方法:

def _format_action_invocation(self, action):
    if not action.option_strings:
        metavar, = self._metavar_formatter(action, action.dest)(1)
        return metavar

    else:
        parts = []

        # if the Optional doesn't take a value, format is:
        #    -s, --long
        if action.nargs == 0:
            parts.extend(action.option_strings)

        # if the Optional takes a value, format is:
        #    -s ARGS, --long ARGS
        else:
            default = action.dest.upper()
            args_string = self._format_args(action, default)
            for option_string in action.option_strings:
                parts.append('%s %s' % (option_string, args_string))

        return ', '.join(parts)

注意parts.append('%s %s' % (option_string, args_string)); 您必须提供您自己的上述方法版本,并将空格替换为=等号。

这样做的问题是,argparse库的未来版本完全可以使用不同的方法名称,从而破坏您的自定义类。

于 2013-05-03T22:30:19.240 回答
0

为了避免上述解决方案的大部分“未来合规性”问题,另一种方法是装饰_format_action_invocation代替。如果方法更改其名称当然不会中断argparse,但至少它允许argparse方法内的代码更新并避免代码重复。

作为奖励,以下解决方案还允许更改使用行中的帮助程序,以保持使用和调用部分之间的一致性:

import re

def deco_argparse_format_action(func, is_invoc=False):
    def wrapper_format_action(*args, **kwargs):
        '''
        Replaces `-f FOO' or  '--foo FOO` by resp. `-f=FOO` and `--foo=FOO` in argparse helper.
        Although there is always possibility to use either `--foo FOO` or
        `--foo=FOO`, it is sometimes better to document the '=' way
        rather than the ' ' way.
        For example, when the option argument contains special characters like '-'
        it must be expressed with '=' in order to not confuse the shell that executes
        the command line.
        '''
        string = func(*args, **kwargs)
        if is_invoc is True:
            # 'invocation section' case
            patt = r"(-+[^ ,]+) +"
            repl = r"\1="
        else:
            # 'usage section' case
            patt = r"(\[-+[^ \]]+) +([^|])"
            repl = r"\1=\2"

        return re.sub(patt,repl,string)
    return wrapper_format_action

用法:

import argparse

#-- Customize helper for options with arguments
#   (print '-f=FOO, --foo=FOO' instead of '-f FOO, --foo FOO')
HelpFormatter._format_action_invocation = deco_argparse_format_action(
        HelpFormatter._format_action_invocation,
        is_invoc = True,
        )

HelpFormatter._format_actions_usage = deco_argparse_format_action(
        HelpFormatter._format_actions_usage,
        )
于 2019-07-23T15:43:11.077 回答