Python argparse如何检测带nargs='*'的参数被调用时无后续传入值
问题解决方案
原因说明
argparse 中 nargs='*' 的默认行为就是:只要参数在命令行被显式指定,哪怕后面没有跟随任何参数值,也会返回空列表[];只有该参数完全没有出现在命令行中时,才会返回你设置的default=None,这是 argparse 的标准设计逻辑。
方案1:自定义参数动作(推荐,准确率最高)
通过自定义 argparse.Action 子类可以精准区分三种状态:参数未被调用、参数被调用但无传参、参数被调用且有传参,示例代码如下:
import argparse # 自定义动作类 class NargsStarDetectAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): # 新增标记位,标记当前参数被显式调用过 setattr(namespace, f"{self.dest}_invoked", True) setattr(namespace, self.dest, values) parser = argparse.ArgumentParser() # 配置--create参数使用自定义动作,同时设置默认标记位为False parser.add_argument('--create', nargs='*', default=None, action=NargsStarDetectAction) parser.add_argument('--mem', type=int) parser.set_defaults(create_invoked=False) args = parser.parse_args() # 检测逻辑 if args.create_invoked: if args.create == []: print("检测到--create被调用,且未传入任何参数") else: print(f"检测到--create被调用,传入参数为:{args.create}") else: print("--create未被调用,使用默认值")
该方案的运行效果对应:
- 命令
./args.py --mem 5:args.create为None,判定为参数未被调用 - 命令
./args.py --create --mem 5:args.create为[],判定为参数被调用且无传参 - 命令
./args.py --create test1 test2 --mem 5:args.create为['test1', 'test2'],判定为参数被调用且有传参
方案2:直接检测命令行参数(适合简单场景)
如果不想修改参数动作,可以直接通过sys.argv判断参数是否出现,示例代码如下:
import sys import argparse parser = argparse.ArgumentParser() parser.add_argument('--create', nargs='*', default=None) parser.add_argument('--mem', type=int) args = parser.parse_args() if '--create' in sys.argv: if args.create == []: print("检测到--create被调用,且未传入任何参数")
该方案的优势是实现简单,劣势是如果参数配置了短别名(比如-c对应--create),需要额外判断短别名是否出现在sys.argv中,同时要避免位置参数值恰好等于--create的边界情况。
内容的提问来源于stack exchange,提问作者SurpriseDog
相关产品推荐
相关产品推荐

