You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python argparse同时使用nargs='*'、choices和default的问题

问题场景

需要实现多个可选位置参数,取值必须限定在指定的choices集合内,默认值为集合中两个选项组成的列表。同时要兼容Python 3.4,且因向后兼容要求不能修改现有接口。

原尝试代码

我最初编写的代码如下,期望默认值为['a', 'd']:

parser = argparse.ArgumentParser()
parser.add_argument('tests', nargs='*', choices=['a', 'b', 'c', 'd'],
                    default=['a', 'd'])
args = parser.parse_args()
print(args.tests)
符合预期的运行结果

以下几种执行场景的输出均符合预期:

$ ./test.py a
['a']
$ ./test.py a d
['a', 'd']
$ ./test.py a e
usage: test.py [-h] [{a,b,c,d} ...]
test.py: error: argument tests: invalid choice: 'e' (choose from 'a', 'b', 'c', 'd')
不符合预期的情况

但直接执行脚本不传入任何参数时,报错结果不符合预期:

$ ./test.py
usage: test.py [-h] [{a,b,c,d} ...]
test.py: error: argument tests: invalid choice: ['a', 'd'] (choose from 'a', 'b', 'c', 'd')
方案探索

我查找了大量类似问题,但均未覆盖该特定场景。找到的可行方案是编写自定义action替代原生choices逻辑。

一开始我抗拒自定义方案,认为这类场景应该有内置解决方式,于是考虑过临时方案:

parser.add_argument('tests', nargs='*',
                    choices=['a', 'b', 'c', 'd', 'default'],
                    default='default')

该方案允许新增参数,且能保持向后兼容。

最终实现

最后还是采用了自定义action方案。虽然一开始抵触,但发现子类化argparse.Action本就是应对这类场景的设计,它能清晰表达逻辑,还能提供最简洁的交互结果。

自定义action代码如下:

class TestsArgAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        all_tests = ['a', 'b', 'c', 'd']
        default_tests = ['a', 'd']

        if not values:
            setattr(namespace, self.dest, default_tests)
            return

        # 无参数时默认值会被当成字符串'default'而非列表['default'],这里统一转成列表
        if not isinstance(values, list):
            values = [values]

        tests = set(values)

        # 处理'all'参数:替换为指定的全部测试项(因兼容原因不包含测试'e')
        try:
            tests.remove('all')
            tests.update(set(all_tests))
        except KeyError:
            pass

        # 处理'default'参数:替换为默认测试项
        try:
            tests.remove('default')
            tests.update(set(default_tests))
        except KeyError:
            pass

        setattr(namespace, self.dest, sorted(list(tests)))

内容的提问来源于stack exchange,提问作者narwahl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 01:09:26