在argparse python3中查找参数的顺序

时间:2019-11-17 19:36:49

标签: python indexing arguments position argparse

我有这个代码

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

2 个答案:

答案 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


我想到了另一个窍门:

如果defaultargparse.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,并重复写以前的值。