我正在使用argparse.ArgumentParser.parse_known_args在给予外部实用程序的命令行上执行一些启发式操作,而只在Python代码中指定其语法的相关部分。但是,当已知和未知的参数以简短形式给出并且在(如ls -lh
)中一起连接时,它不会检测到它们。
例如:
import argparse
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-x', action='store_true')
parser.add_argument('-y', action='store_true')
parser.parse_known_args(['-xy', '-z']) # OK, gives: (Namespace(x=True, y=True), ['-z']
parser.parse_known_args(['-xyz']) # Fails with: PROG: error: argument -y: ignored explicit argument 'z'
有没有办法让它在这种情况下做出更好的启发式方法?
答案 0 :(得分:1)
我通过编写一个函数来分离聚集在一起的参数(使用一些简化的假设)来解决这个问题:
import itertools
import re
def normalizeShortFormArgs(args):
"Separate short form args clustered together (as in 'ls -lh') into individual args (as in 'ls -l -h')"
shortArgsRe = re.compile(r"\-(\w+)")
def normalizeToken(argToken):
m = shortArgsRe.match(argToken)
if m is None:
return (argToken,)
else:
return ("-" + c for c in m.group(1))
return type(args)(itertools.chain.from_iterable(map(normalizeToken, args)))
# Example: normalizeShortFormArgs(["-k", "-lhZ", "-", "--other"])
# Gives: ['-k', '-l', '-h', '-Z', '-', '--other']
答案 1 :(得分:1)
我在https://bugs.python.org/issue32756上回复了类似的问题。
正如我所指出的,argparse
文档不承诺根据需要处理此类输入:
从文档中,16.4.4.1。选项值语法
对于短选项(选项只有一个字符长),可以连接选项及其值:
只要使用单个前缀,只要最后一个选项(或者没有一个)需要值,就可以将几个短选项连接在一起:
在您的情况下' z'既不是短期期权也不是短期期权的价值,所以它被拒绝了。
所以是的,预处理输入是唯一的选择。
' -xyz'在哪里' -x'和' -y'已知,但' z'本质上并不含糊。它是' -x -y -z',' -x -y z',' -x -y = z'。 argparse
提出错误而不是做出其中一个假设。