如果参数未出现,Argparse append操作将带有默认值

9
我正在使用argparse库解析程序中的CLI参数。我想解析一个可以重复的参数,其行为如下:
  • 如果参数至少出现一次,则将其值存储在列表中,
  • 如果参数没有出现,则值为默认列表。
到目前为止,我的代码如下:
import argparse
ap = argparse.ArgumentParser(description="Change channel colours.")
ap.add_argument('-c', '--channel', action='append', default=['avx', 'fbx'])
print(ap.parse_known_args(['-c', 'iasdf', '-c', 'fdas']))
print(ap.parse_known_args())

这样设置默认列表是合适的,但是当参数出现时,它并不以空列表开始。换句话说,第二个print语句打印了正确的值(即默认列表),但第一个语句打印的是:

['avx', 'fbx', 'iasdf', 'fdas']

替代

['iasdf', 'fdas']
argparse有没有一种方法可以实现我的要求,而不需要像下面这样做
if len(args.channel) > 2:
    args.channel = args.channel[2:]

过后再做?


1
  1. 你可以反过来做 - 从解析器本身中删除默认值,然后仅在为空时检查并附加默认值。
  2. 你可以尝试使用相同目标的互斥组?真正的“-c”将具有空的默认值,而虚拟的则将具有真实的默认值?我不确定这是否有效。我会尝试这个想法并回到你那里。
- h4z3
1
你还可以通过传递Action子类或其他实现相同接口的对象来指定任意操作。建议的方法是扩展Action,重写__call__方法和可选的__init__ 方法。关于Action本身的文档: https://docs.python.org/3/library/argparse.html#argparse.Action - h4z3
1个回答

9

这个行为存在一个 bug/问题。我在讨论中写了几篇文章。

https://bugs.python.org/issue16399 argparse:使用默认列表的添加操作会将其添加到列表中而不是覆盖它们

目前唯一的变化在于文档,而不是行为。

所有默认值都在解析开始时放置在命名空间中。对于普通操作,用户值会覆盖默认值。但是,在附加情况下,它们只是添加到已有内容中。它不会试图区分由默认值和之前的用户值放置的值。

我认为最简单的解决方案是保留默认值,并在解析后检查是否为None或空列表(我不记得哪个),然后插入您的默认值。你不需要为在argparse中完成所有解析而获得额外的分数。进行一些后处理是非常好的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接