配置argparse以接受引用的参数

时间:2017-07-17 14:19:56

标签: python argparse

我正在编写一个程序,除其他外,它允许用户通过参数指定要加载的模块(然后用于执行操作)。我试图建立一种方法来轻松地将参数传递给这个内部模块,并且我试图使用ArgParse action='append'来构建一个我将通过的参数列表。 / p>

以下是我正在使用的参数的基本布局

parser.add_argument('-M', '--module',
                    help="Module to run on changed files - should be in format MODULE:CLASS\n\
                          Specified class must have function with the signature run(src, dest)\
                          and return 0 upon success",
                    required=True)
parser.add_argument('-A', '--module_args',
                    help="Arg to be passed through to the specified module",
                    action='append',
                    default=[])

然而 - 如果我然后尝试使用python my_program -M module:class -A "-f filename"(我希望通过-f filename到我的模块)运行此程序,它似乎正在解析-f作为其自己的论点(我得到错误my_program: error: argument -A/--module_args: expected one argument

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

解决方案是接受任意论证 - 这是argparse的文档here中的一个例子:

  

argparse.REMAINDER。所有剩余的命令行参数都收集到一个列表中。这对于调度到其他命令行实用程序的命令行实用程序通常很有用:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')

答案 1 :(得分:1)

使用:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-M', '--module',
                    help="Module to run on changed files - should be in format MODULE:CLASS\n\
                          Specified class must have function with the signature run(src, dest)\
                          and return 0 upon success",
                    )
parser.add_argument('-A', '--module_args',
                    help="Arg to be passed through to the specified module",
                    action='append',
                    default=[])
import sys
print(sys.argv)
print(parser.parse_args())

我明白了:

1028:~/mypy$ python stack45146728.py -M module:class -A "-f filename"
['stack45146728.py', '-M', 'module:class', '-A', '-f filename']
Namespace(module='module:class', module_args=['-f filename'])

这是使用linux shell。引用的字符串保留一个字符串,如sys.argv中所示,并被正确解释为-A的参数。

如果没有引号,-f是独立的并被解释为标志。

1028:~/mypy$ python stack45146728.py -M module:class -A -f filename
['stack45146728.py', '-M', 'module:class', '-A', '-f', 'filename']
usage: stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS]
stack45146728.py: error: argument -A/--module_args: expected one argument

你是否正在使用windows或其他一些不能以相同方式处理报价的OS / shell?

Argparse `append` not working as expected

你问过一个稍微不同的命令行:

1032:~/mypy$ python stack45146728.py  -A "-k filepath" -A "-t"
['stack45146728.py', '-A', '-k filepath', '-A', '-t']
usage: stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS]
stack45146728.py: error: argument -A/--module_args: expected one argument

正如我已经指出的那样-k filepath作为一个字符串传递。由于空间,argparse不会将其解释为旗帜。但它确实解释了裸露的' -t'作为旗帜。

有一个错误/问题是关于解释未定义的' -xxx'字符串作为参数而不是标志。我必须仔细研究是否有任何东西进入生产阶段。

可以在argparse.ArgumentParser._parse_optional方法中找到字符串如何分类为标志或参数的详细信息。它包含一条评论:

    # if it contains a space, it was meant to be a positional
    if ' ' in arg_string:
        return None

http://bugs.python.org/issue9334 argparse does not accept options taking arguments beginning with dash (regression from optparse)是关于该主题的旧的长期错误/问题。