Python Argparse parse_known_args 连接短选项时失败

Python Argparse parse_known_args fails when short options are joined

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

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

我通过编写一个函数来分离聚集在一起的参数(使用一些简化的假设)来解决这个问题:

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

我在 https://bugs.python.org/issue32756 上回复了类似的问题。

正如我在此处指出的那样 argparse 文档不承诺按您的意愿处理此类输入:

来自文档,16.4.4.1。选项值语法

For short options (options only one character long), the option and its value can be concatenated:

Several short options can be joined together, using only a single - prefix, as long as only the last option (or none of them) requires a value:

在你的情况下 'z' 既不是空头期权也不是空头期权的价值,所以它被拒绝了。

所以是的,预处理输入是唯一的选择。


'-xyz' 其中 '-x' 和 '-y' 是已知的,但 'z' 不是,本质上是模棱两可的。是'-x -y -z'、'-x -y z'、'-x -y=z'。 argparse 提出错误而不是做出这些假设之一。