Argparse 不会识别参数

如何解决Argparse 不会识别参数

此脚本将打印环境变量。

使用 Python 3.9。 目标是能够在需要时运行任何子命令。我得到的错误是,如果添加了任何额外的短标志,“忽略环境”arg 会尝试解析它。我不要这个。额外的短标志指向 --eval 之后分配的任何内容

解析器.py

import argparse,os 

def parseargs(p):
    p.usage = '%(prog)s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]'
    p.add_argument(
        "-i","--ignore-environment",action="store_const",const=dict(),dest="env",help="start with an empty environment",default=os.environ,)
    p.add_argument(
        "--export",nargs=1,help="Set argument with --export NAME=VALUE"
    )
    p.add_argument(
        "--eval",nargs="+",help="Run any commands with newly updated environment," 
            "--eval COMMAND ARGS"
    )
return p

执行如下

>>> p = argparse.ArgumentParser()
>>> parseargs(p) # assigns arguments to parser
>>> p.parse_args('--export FOO=bar --eval cat test.py'.split()) # This is ok and works correctly. cat is the bash command
Namespace([os.environs..],eval=['cat','test.py'],export=['FOO=bar']) 
>>>p.parse_args('--export FOO=bar --eval ls -l'.split()) # This is fails
error: unrecognized arguments: -l

如何让“-l”被“-i/ignore environment”忽略但传递给eval,例如使用cat test.py。我曾尝试使用 sub_parser 但无济于事。出现同样的结果。

解决方法

问题在于,parse_args 在考虑任何实际选项的语义之前,会尝试从词法上识别可能选项。

由于采用可变数量参数的选项几乎必须是始终使用的 last 选项,请考虑将 --eval 设置为一个标志,用于告诉您的程序如何解释剩余的位置参数。那么ls-l可以被--抵消,防止parse_args认为-l是一个未定义的选项。

p.add_argument(
    "--eval",action='store_true',help="Run any commands with newly updated environment," 
)

# zero or more,so that you don't have to provide a dummy argument
# when the lack of --eval makes a command unnecessary.
# Wart: you can still use --eval without specifying any commands.
# I don't believe argparse alone is capable of handling this,# at least not in a way that is simpler than just validating
# arguments after calling parse_args().
p.add_argument('cmd_and_args',nargs='*')

那么你的命令行可能看起来像

>>> p.parse_args('--export FOO=bar --eval -- ls -l'.split())

甚至

>>> p.parse_args('--eval --export FOO=bar -- ls -l'.split())

稍后,您将使用 args.eval 的布尔值来决定如何处理列表 args.cmd_and_args

重要提示: 一个问题是,您将这些选项附加到任意预先存在的解析器,这些解析器可能定义了自己的位置参数,因此让它与原始解析器配合使用可能会很好很难,如果不是不可能的话。


另一种选择是采用单个参数进行内部解析。

p.add_arguments("--eval")

...

args = p.parse_args()
cmd_and_args = shlex.split(args.eval)  # or similar

然后

>>> p.parse_args(['--export','FOO=bar','--eval','ls -l'])

(请注意,使用 str.split 不适用于 --export FOO=bar --eval "ls -l" 之类的命令行。)

,

来自Argparse documentation

如果您的位置参数必须以 - 开头并且看起来不像负数,则可以插入伪参数“--”,它告诉 parse_args() 之后的所有内容都是位置参数 [... ]

因此,在您的情况下,您无法更改添加或定义参数的方式,但是您提供的要解析的字符串应该在 eval 选项的参数前面有 --,如下所示:

--export FOO=bar --eval ls -- -l

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?