【发布时间】:2019-09-22 23:18:49
【问题描述】:
我正在尝试模拟 Python 解释器的命令行行为,如帮助文本所示:
command [options] [-m mod | file] [arg] ...
即:
- 任意数量的任意选项(形式为
-[a-zA-Z],用作标志或带有单个参数) - 之一:
- -m 模组
- 文件
- 零个或多个应按原样提供的参数
我尝试过使用内置的 argparse 模块,但没有成功。
import argparse
parser = argparse.ArgumentParser()
selector = parser.add_mutually_exclusive_group(required=True)
selector.add_argument('file', nargs='?', help='path to script')
selector.add_argument('-m', help='module name')
parser.add_argument('args', nargs=argparse.REMAINDER)
parser.parse_args(['-m', 'hello', '--', 'arg1'])
运行这个会产生
usage: test.py [-h] [-m M] [file] ...
test.py: error: argument file: not allowed with argument -m
这是有道理的,因为 argparse 似乎通常忽略选项的顺序 - 解析选项后剩余的任何位置参数都会按照指定从第一个到最后一个填充位置参数。
我已经尝试定义自定义argparse.Actions 来完成这项工作,但它最终看起来很hacky,因为与组中的一个参数对应的Action 类需要保存一个累积值以便以后包含在@ 987654327@.
我也尝试过对parser.parse_args 的输入进行预处理,但不喜欢这种方法,因为有关哪些选项具有值的信息(以将选项参数与file 参数区分开来)以及哪些选项是一组终端参数(应被视为传递参数[arg] ... 的开始)将在argparse.add_argument... 调用和预处理代码之间重复。
什么是好的方法(除了需要提供路径,例如-f)?
附加限制:
- 我更喜欢使用
argparse或具有良好界面的东西,该界面将参数与帮助文本相关联并且加载时间不长(对我来说,argparse 导入只需 6 毫秒) - 我只需要兼容 Python 3.6 及以上版本即可。
- 这并不理想,但我可以要求用户将
--作为第一个arg,如果后续参数(将传递给模块或文件)以-开头,或者可能是被误认为[options]中的某些内容。
【问题讨论】:
-
我认为如果首先定义了
-m,那么mutual_exclusive 用法会正确显示。但这并不能解决file的?和用于args的字符串之间的干扰。file获取第一个“位置”字符串,无论是否提供了-m。 -
一般来说,两个变量编号为
nargs的位置不能很好地协同工作。第一个先被填满。第二个只得到“剩余”,并且可能对空列表“满意”。