我有这个代码
parser = argparse.ArgumentParser()
parser.add_argument('--input')
parser.add_argument('--min')
parser.add_argument('--max')
args = parser.parse_args()
我怎么知道参数的顺序?例如,如果我输入:
python somefile.py --min min --input file.csv
我怎么知道--min
的位置在--input
之前并且用户没有键入--max
?
答案 0 :(得分:1)
我认为从解析器本身获取该信息可能很棘手,但是可以很容易地从sys.argv获取该信息:
def get_arg_index(args: list, name: str):
return next((i for i, v in enumerate(args) if v.startswith(name)), None)
print(get_arg_index(sys.argv, "--min"))
print(get_arg_index(sys.argv, "--max"))
答案 1 :(得分:1)
根据设计,argparse
应该以任何顺序处理optionals
。它们将按照在命令行中提供的顺序进行解析,但是不会保留该顺序的任何记录。 positionals
(不带关键字)的处理顺序由add_argument
定义定义。
在解析开始时,所有属性及其默认值都会添加到args
命名空间中。并以add_argument
顺序执行此操作。在较新的Python中,此顺序保留在args.__dict__
中(vars(args)
也显示了)。
但是在print(args)
中,属性按排序顺序显示。 usage
还会保留optionals
的定义顺序。
因此对于示例解析器:
In [11]: p.print_usage()
usage: ipython3 [-h] [--foo FOO] [--test TEST] [--aaa AAA] bar
In [12]: args=p.parse_args(['xxx'])
In [13]: args
Out[13]: Namespace(aaa=None, bar='xxx', foo=None, test=None) # sorted
In [14]: vars(args)
Out[14]: {'foo': None, 'bar': 'xxx', 'test': None, 'aaa': None} # definition
In [15]: [a.dest for a in p._actions]
Out[15]: ['help', 'foo', 'bar', 'test', 'aaa'] # definition order
仅凭argparse
来记录命令行中参数的出现顺序就很尴尬。从某种意义上说,它违背了optionals
的精神。
替代品:
直接与sys.argv
自定义action
类
自定义Namespace
类
我想到了另一个窍门:
如果default
是argparse.SUPPRESS
,则默认值不会添加到args
中。然后我认为var(args)
的顺序将是解析和添加值的顺序。
In [16]: for a in p._actions: a.default=argparse.SUPPRESS
In [24]: args=p.parse_args(['--test', 'ttt','xxx','--foo=3'])
In [25]: args
Out[25]: Namespace(bar='xxx', foo='3', test='ttt')
In [26]: vars(args)
Out[26]: {'test': 'ttt', 'bar': 'xxx', 'foo': '3'}
用户可以重复optionals
,并重复写以前的值。