且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Python 3 argparse:仅当未提供可选参数时才需要条件参数?

更新时间:2023-11-30 21:06:22

这是一个简单的解析器,它使位置参数可选 (nargs=?).

Here's a simple parser that makes the positional argument optional (nargs=?).

In [171]: parser=argparse.ArgumentParser()
In [172]: parser.add_argument('func', nargs='?',default='foo')
In [173]: parser.add_argument('--list',action='store_true')
In [174]: args=parser.parse_args(['--list'])
In [175]: args
Out[175]: Namespace(func='foo', list=True)
In [176]: args=parser.parse_args(['bar'])
In [177]: args
Out[177]: Namespace(func='bar', list=False)
In [178]: parser.parse_args(['--list','bar'])
Out[178]: Namespace(func='bar', list=True)
In [179]: parser.parse_args([])
Out[179]: Namespace(func='foo', list=False)

不要给位置参数一个 dest 参数;它已经在第一个字符串中获得了一个.store_true 动作不需要默认值;它会自动获取 False.

Don't give a positional argument a dest parameter; it already gets one in the first string. store_true action doesn't need a default; it gets False automatically.

有了这个设置,你可以检查args.list;它 True,然后忽略 args.func 值.如果 False,则使用 args.func.如果你给了 func 一个有意义的默认值,那么用户是否给你一个值并不重要.换句话说,它真的不是必需的.(如果需要,定义默认值没有意义).或者你可以反对,如果他们给你两个:

With this set up, you could check args.list; it True, then just ignore the args.func value. If False, use the args.func. If you have given func a meaningful default, if shouldn't matter whether the user gives you a value or not. In other words, it really isn't required. (And if required there's no point in defining a default). Or you could object if they give you both:

In [184]: args=parser.parse_args(['--list','bar'])
In [185]: if args.list and args.func!='foo':
       parser.error('you stupid user ...')
   .....:     
usage: ipython3 [-h] [--list] [func]
ipython3: error: you stupid user ...

我们可以更进一步,将这 2 个参数放在 mutually_exclusive_group 中,并使该组成为 required.这样的一个组接受一个这样的可选位置.我认为文档已经足够清楚,但如果需要,我可以扩展我的答案.

We could go the further step of placing these 2 arguments in a mutually_exclusive_group, and making that group required. Such a group accepts one optional positional like this. I think the docs are clear enough, but I could expand my answer if needed.