Argparse,处理可重复的项目集 [英] Argparse, handle repeatable set of items

查看:16
本文介绍了Argparse,处理可重复的项目集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以创建一组相关且可重复的可选参数?

假设我有三个参数 -a, -b, -c 组成一个集合, -a 是必需的,但 -b 和 -c 是可选的.(更新)

我希望能够指定多组这些.

Script.py -a 1 -b 2 -c 3 -a 4 -c 6 -a 7 -b 8 -a 10

这将被解析为一个字典列表,如下

<预><代码>[{a":1,b":2,c":3},{"a":4, "c":6},{"a":7, "b":8},{"a":10}]

解决方案

使参数可重复的一种方法是使用附加"操作类型:

导入 argparse解析器 = argparse.ArgumentParser()parser.add_argument('-a', action='append')parser.add_argument('-b', action='append')parser.add_argument('-c', action='append')argv = '-a 1 -b 2 -c 3 -a 4 -c 6 -a 7 -b 8 -a 10'args = parser.parse_args(argv.split())打印参数

产生:

命名空间(a=['1', '4', '7', '10'], b=['2', '8'], c=['3', '6'])

不幸的是,它确实丢失了一些信息.没有办法将4"与6"而不是8"联系起来.

如果您使用--"来分隔参数块,那么这个迭代解析器可能会完成这项工作:

parser = argparse.ArgumentParser()# SUPPRESS 将默认的 None 保留在命名空间之外parser.add_argument('-a', type=int, default=argparse.SUPPRESS, required=True)parser.add_argument('-b', type=int, default=argparse.SUPPRESS)parser.add_argument('-c', type=int, default=argparse.SUPPRESS)argv = '-a 1 -b 2 -c 3 -- -a 4 -c 6 -- -a 7 -b 8 -- -a 10'参数列表 = []休息 = argv.split()休息时:args,rest = parser.parse_known_args(rest)rest = rest[1:] # 删除第一个 '--'打印参数arglist.append(vars(args))打印参数列表

制作:

命名空间(a=1, b=2, c=3)命名空间(a=4, c=6)命名空间(a=7, b=8)命名空间(a=10)[{'a':1,'c':3,'b':2},{'a':4,'c':6},{'a':7,'b':8},{'a':10}]

我不确定它是否足够健壮.我将 -a 设为必需,因此从其中一个组中省略它会引发错误.

<小时>

或者调整 farzad 的迭代器:

def by_sets(iterator, start):设置 = []对于迭代器中的 val:如果设置和 val == 开始:产量集设置 = [val]别的:set.append(val)产量集argv = '-a 1 -b 2 -c 3 -a 4 -c 6 -a 7 -b 8 -a 10'# 打印列表(by_sets(argv.split(), '-a'))# [['-a', '1', '-b', '2', '-c', '3'], ['-a', '4', '-c', '6'],... ['-a', '10']]参数列表 = []对于 by_sets(argv.split(), '-a') 中的资产:arglist.append(vars(parser.parse_args(aset)))打印参数列表

产生:

[{'a': 1, 'c': 3, 'b': 2}, {'a': 4, 'c': 6}, {'a': 7, 'b': 8}, {'a': 10}]

循环也可以写成理解:

[vars(parser.parse_args(aset)) for aset in by_sets(argv.split(), '-a')]

Is it possible to create a set of optional arguments that are related and repeatable?

Let's say I have three arguments -a, -b, -c that form a set, -a is required, but -b and -c are optional. (Updated)

I would like an ability to specify multiple set of these.

Script.py -a 1 -b 2 -c 3    -a 4 -c 6   -a 7 -b 8    -a 10

This will be parsed as a list of dict as follows

[
    {"a":1, "b":2, "c":3},
    {"a":4, "c":6},
    {"a":7, "b":8},
    {"a":10}
]

解决方案

A way to make arguments repeatable is to use an 'append' action type:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-a', action='append')
parser.add_argument('-b', action='append')
parser.add_argument('-c', action='append')
argv = '-a 1 -b 2 -c 3    -a 4 -c 6   -a 7 -b 8    -a 10'
args = parser.parse_args(argv.split())
print args

produces:

Namespace(a=['1', '4', '7', '10'], b=['2', '8'], c=['3', '6'])

Unfortunately it does lose some information. There's no way to associate the '4' with the '6' instead of the '8'.

If you use '--' to separate blocks of arguments, then this iterative parser might do the job:

parser = argparse.ArgumentParser()
# SUPPRESS keeps the default None out of the namespace
parser.add_argument('-a', type=int, default=argparse.SUPPRESS, required=True)
parser.add_argument('-b', type=int, default=argparse.SUPPRESS)
parser.add_argument('-c', type=int, default=argparse.SUPPRESS)
argv = '-a 1 -b 2 -c 3  --  -a 4 -c 6 --  -a 7 -b 8  --  -a 10'

arglist = []
rest = argv.split()
while rest:
    args,rest = parser.parse_known_args(rest)
    rest = rest[1:]  # remove the 1st '--'
    print args
    arglist.append(vars(args))
print arglist

producing:

Namespace(a=1, b=2, c=3)
Namespace(a=4, c=6)
Namespace(a=7, b=8)
Namespace(a=10)

[{'a': 1, 'c': 3, 'b': 2}, 
 {'a': 4, 'c': 6}, 
 {'a': 7, 'b': 8}, 
 {'a': 10}]

I'm not sure if it is robust enough. I made -a required, so omitting it from one of the groups will raise an error.


Or adapting farzad's iterator:

def by_sets(iterator, start):
    set = []
    for val in iterator:
        if set and val == start:
            yield set
            set = [val]
        else:
            set.append(val)
    yield set

argv = '-a 1 -b 2 -c 3  -a 4 -c 6 -a 7 -b 8  -a 10'
# print list(by_sets(argv.split(), '-a'))
# [['-a', '1', '-b', '2', '-c', '3'], ['-a', '4', '-c', '6'],... ['-a', '10']]

arglist = []
for aset in by_sets(argv.split(), '-a'):
    arglist.append(vars(parser.parse_args(aset)))
print arglist

produces:

[{'a': 1, 'c': 3, 'b': 2}, {'a': 4, 'c': 6}, {'a': 7, 'b': 8}, {'a': 10}]

The loop can also be written as a comprehension:

[vars(parser.parse_args(aset)) for aset in by_sets(argv.split(), '-a')]

这篇关于Argparse,处理可重复的项目集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆