加入短选项时,Python Argparse parse_known_args失败

时间:2018-03-20 13:38:39

标签: python command-line-arguments argparse

我正在使用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'

有没有办法让它在这种情况下做出更好的启发式方法?

2 个答案:

答案 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提出错误而不是做出其中​​一个假设。