我正在尝试模拟Python解释器的命令行行为,如帮助文本所示:
command [options] [-m mod | file] [arg] ...
也就是说:
-[a-zA-Z]
,用作标志或带有单个参数)我尝试使用内置的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.Action
来完成这项工作,但最终看起来很hacky,因为与该组中一个参数相对应的Action
类需要为以后包含在args
中。
我也尝试过对parser.parse_args
的输入进行预处理,但是不喜欢这种方法,因为有关哪些选项具有值(以将选项参数与file
参数区分开)的信息是终端参数组的一部分(应将其视为直通参数[arg] ...
的开始)将在argparse.add_argument
...调用与预处理代码之间重复。>
什么是好的方法(除了要求提供路径-f
之外)?
其他限制:
argparse
或具有良好接口的东西,该接口可以关联参数以帮助文本,并且加载时间不长(对我来说,argparse的导入时间为6毫秒)--
作为第一个arg
}},否则可能会误认为-
中的内容。答案 0 :(得分:0)
即使没有相互排斥的分组,file
和args
也不能很好地发挥作用:
In [2]: parser = argparse.ArgumentParser()
In [3]: parser.add_argument('-m');
In [4]: parser.add_argument('file', nargs='?');
In [6]: parser.add_argument('args', nargs=argparse.REMAINDER);
确定:
In [7]: parser.parse_args('-m foo a b c '.split())
Out[7]: Namespace(args=['b', 'c'], file='a', m='foo')
'-'只允许我们使用'-b'作为纯字符串:
In [8]: parser.parse_args('-m foo a -- -b c '.split())
Out[8]: Namespace(args=['-b', 'c'], file='a', m='foo')
'a'进入'file',其余部分进入'args'-这是因为所有“连续”位置都被一起求值。使用remainder
,-m
标志将被忽略,并被视为纯字符串。
In [9]: parser.parse_args('a -m foo -- -b c '.split())
Out[9]: Namespace(args=['-m', 'foo', '--', '-b', 'c'], file='a', m=None)
In [10]: parser.parse_args('a -- -b c '.split())
Out[10]: Namespace(args=['-b', 'c'], file='a', m=None)
参数分配甚至在调用Action
之前就已发生,因此自定义Action类不会改变这种行为。
模糊的参数可以使您最好地控制顺序和互斥。