2

我用docopt创建了一个 cli 规范,效果很好,但是由于某种原因,我必须将其重写为 argparse

Usage:
    update_store_products <store_name>...
    update_store_products --all

    Options:
      -a --all     Updates all stores configured in config

怎么做?

重要的是我不想拥有这样的东西:

update_store_products [--all] <store_name>...

我认为它会是这样的:

update_store_products (--all | <store_name>...)

我尝试使用add_mutually_exclusive_group,但出现错误:

ValueError: mutually exclusive arguments must be optional
4

1 回答 1

10

首先,您应该在问题本身中包含重现错误所需的最短代码。没有它,答案只是在黑暗中开枪。

现在,我敢打赌你的argparse定义看起来有点像这样:

parser = ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--all', action='store_true')
group.add_argument('store_name', nargs='*')

互斥组中的参数必须是可选的,因为在那里有一个必需的参数没有多大意义,因为该组只能有那个参数。仅凭 -创建动作的属性将- 说服互斥锁组该参数是真正可选的是nargs='*'不够的。你需要做的是添加一个默认值:requiredTrue

parser = ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('--all', action='store_true')
group.add_argument('store_name', nargs='*', default=[])

这将导致:

[~]% python2 arg.py
usage: arg.py [-h] (--all | store_name [store_name ...])
arg.py: error: one of the arguments --all store_name is required

[~]% python2 arg.py --all
Namespace(all=True, store_name=[])

[~]% python2 arg.py store1 store2 store3
Namespace(all=False, store_name=['store1', 'store2', 'store3'])
于 2016-04-25T06:38:08.290 回答