配置 argparse 以接受带引号的参数
Configure argparse to accept quoted arguments
我正在编写一个程序,除其他外,该程序允许用户通过参数指定要加载的模块(然后用于执行操作)。我正在尝试设置一种方法来轻松地将参数传递给这个内部模块,并且我试图使用 ArgParse 的 action='append'
来构建一个参数列表,然后我将通过该列表。
这是我使用的参数的基本布局
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
有什么想法吗?
解决方案是接受任意参数 - argparse 的文档中有一个示例 here:
argparse.REMAINDER. All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities:
>>> 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')
有:
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?
在
您询问的命令行略有不同:
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
作为一个字符串传递。由于 space,argparse
不会将其解释为标志。但它确实将裸露的“-t”解释为标志。
有一个 bug/issue 关于将未定义的 '-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)
是一个古老而漫长的话题 bug/issue。
我正在编写一个程序,除其他外,该程序允许用户通过参数指定要加载的模块(然后用于执行操作)。我正在尝试设置一种方法来轻松地将参数传递给这个内部模块,并且我试图使用 ArgParse 的 action='append'
来构建一个参数列表,然后我将通过该列表。
这是我使用的参数的基本布局
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
有什么想法吗?
解决方案是接受任意参数 - argparse 的文档中有一个示例 here:
argparse.REMAINDER. All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities:
>>> 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')
有:
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?
在
您询问的命令行略有不同:
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
作为一个字符串传递。由于 space,argparse
不会将其解释为标志。但它确实将裸露的“-t”解释为标志。
有一个 bug/issue 关于将未定义的 '-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)
是一个古老而漫长的话题 bug/issue。