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
提出错误而不是做出这些假设之一。
我正在使用 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
提出错误而不是做出这些假设之一。