【问题标题】:How to parse multiple positional arguments from a list of choices?如何从选择列表中解析多个位置参数?
【发布时间】:2019-09-27 09:59:35
【问题描述】:

我需要编写一个 django 管理命令(与 django 无关)来启动 worker。我从docker-compose up 获得灵感,并希望有以下行为:

>>> services = ['a', 'b', 'c']
>>> import argparse
>>> ap = argparse.ArgumentParser()
>>> ap.add_argument('services', ???)
>>> ap.parse_args(''.split())
Namespace(services=[])
>>> ap.parse_args('a b'.split())
Namespace(services=['a', 'b'])
>>> ap.parse_args('a b d'.split())
: error: argument services: invalid choice: 'd' (choose from 'a', 'b', 'c')
>>> ap.parse_args('a b b'.split())
: error: argument services: duplicated choice: 'b'

目前,我已经测试了几种方法,但主要障碍是如果提供 choices=servicesnargs='*' 不再允许 0 参数。

>>> ap.add_argument('services', choices=services, nargs='*')
>>> ap.parse_args(''.split())
usage: [-h] [{a,b,c} [{a,b,c} ...]]
: error: argument services: invalid choice: [] (choose from 'a', 'b', 'c')

虽然有一种可行的解决方案(具有自定义类型)和一种解决方法(稍后验证),但它们感觉不对。 (另一种解决方案已作为答案发布,但如果存在的话,我很乐意看到更好的解决方案。)

(看起来“无重复”功能在 Python 中不是原生的,需要覆盖 argparse.Actionprobably starting here。)

编辑:我已经放弃坚持它必须像上面的规范一样工作。解决方法要好得多。我只是做ap.add_argument('--a', dest='services', action='append_const', const=AaaService),我的命名空间有一个services attr,其中包含我要运行的所有服务类。

【问题讨论】:

  • 后解析检查将是最简单的,因为你们都想处理无和重复。尝试在argparse 内执行此操作不会获得额外积分。

标签: python argparse


【解决方案1】:

这是一个已知问题,是对“*”位置的 default 进行一些特殊处理的结果。

Python argparse: type inconsistencies when combining 'choices', 'nargs' and 'default'

https://bugs.python.org/issue9625

https://bugs.python.org/issue27227

解析后做一些自己的值验证没有错。通用解析工具无法处理用户向其抛出的所有情况!

【讨论】:

    【解决方案2】:

    另一种解决方案是将[](文字空列表)添加到choices

    >>> ap.add_argument('services', choices=services + [[]], nargs='*')
    >>> ap.parse_args(''.split())
    Namespace(services=[])
    

    这是由于nargs 生成了一个空列表,而choices 针对结果进行了验证。 choices kwarg 变为 ['a', 'b', 'c', []],这看起来很奇怪,但这就是这两个选项一起工作所需要的。

    【讨论】:

      猜你喜欢
      • 2021-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2015-06-19
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多