配置 argparse 以接受带引号的参数 [英] Configure argparse to accept quoted arguments

查看:30
本文介绍了配置 argparse 以接受带引号的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我使用的参数的基本布局

parser.add_argument('-M', '--module',help="在更改的文件上运行的模块 - 格式应为 MODULE:CLASS\n\指定的类必须具有签名为 run(src, dest)\ 的函数并在成功时返回 0",必需=真)parser.add_argument('-A', '--module_args',help="要传递给指定模块的参数",动作='追加',默认=[])

但是 - 如果我然后尝试使用 python my_program -M module:class -A "-f filename" 运行这个程序(我想通过 -f 文件名 到我的模块)它似乎正在解析 -f 作为它自己的参数(我得到错误 my_program: error: argument -A/--module_args: expected one参数

有什么想法吗?

解决方案

With:

导入 argparse解析器 = argparse.ArgumentParser()parser.add_argument('-M', '--module',help="在更改的文件上运行的模块 - 格式应为 MODULE:CLASS\n\指定的类必须具有签名为 run(src, dest)\ 的函数并在成功时返回 0",)parser.add_argument('-A', '--module_args',help="要传递给指定模块的参数",动作='追加',默认=[])导入系统打印(sys.argv)打印(解析器.parse_args())

我明白了:

1028:~/mypy$ python stack45146728.py -M module:class -A "-f 文件名"['stack45146728.py', '-M', 'module:class', '-A', '-f 文件名']命名空间(module='module:class', module_args=['-f 文件名'])

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

没有引号的 -f 是单独的并被解释为一个标志.

1028:~/mypy$ python stack45146728.py -M module:class -A -f 文件名['stack45146728.py', '-M', 'module:class', '-A', '-f', '文件名']用法:stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS]stack45146728.py:错误:参数-A/--module_args:需要一个参数

您使用的是 windows 还是其他一些不能以相同方式处理引号的 OS/shell?

<小时>

Argparse `append` 未按预期工作

您询问了稍微不同的命令行:

1032:~/mypy$ python stack45146728.py -A "-k 文件路径" -A "-t"['stack45146728.py', '-A', '-k 文件路径', '-A', '-t']用法:stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS]stack45146728.py:错误:参数-A/--module_args:需要一个参数

正如我已经注意到的 -k filepath 作为一个字符串传递.由于空间原因,argparse 不会将其解释为标志.但它确实将裸露的 '-t' 解释为一个标志.

有一个关于将未定义的-xxx"字符串解释为参数而不是标志的可能性的错误/问题.我得查一下,看看有没有什么东西可以投入生产.

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

<块引用>

 # 如果它包含一个空格,它应该是一个位置如果 ' ' 在 arg_string 中:返回无

http://bugs.python.org/issue9334 argparse 不接受选项以 dash 开头的参数(从 optparse 回归) 是该主题的一个古老而长期的错误/问题.

I am writing a program which, among other things, allows the user to specify through an argument a module to load (and then use to perform actions). I am trying to set up a way to easily pass arguments through to this inner module, and I was attempting to use ArgParse's action='append' to have it build a list of arguments that I would then pass through.

Here is a basic layout of the arguments that I am using

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=[])

However - if I then try to run this program with python my_program -M module:class -A "-f filename" (where I would like to pass through the -f filename to my module) it seems to be parsing the -f as its own argument (and I get the error my_program: error: argument -A/--module_args: expected one argument

Any ideas?

解决方案

With:

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())

I get:

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'])

This is using a linux shell. The quoted string remains one string, as seen in the sys.argv, and is properly interpreted as an argument to -A.

Without the quotes the -f is separate and interpreted as a flag.

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

Are you using windows or some other OS/shell that doesn't handle quotes the same way?


In Argparse `append` not working as expected

you asked about a slightly different command line:

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

As I already noted -k filepath is passed through as one string. Because of the space, argparse does not interpret that as a flag. But it does interpret the bare '-t' as a flag.

There was a bug/issue about the possibility of interpreting undefined '-xxx' strings as arguments instead of flags. I'd have to look that up to see whether anything made it into to production.

Details of how strings are categorized as flag or argument can be found in argparse.ArgumentParser._parse_optional method. It contains a comment:

    # 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) is an old and long bug/issue on the topic.

这篇关于配置 argparse 以接受带引号的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆