【发布时间】: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=services,nargs='*' 不再允许 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.Action、probably starting here。)
编辑:我已经放弃坚持它必须像上面的规范一样工作。解决方法要好得多。我只是做ap.add_argument('--a', dest='services', action='append_const', const=AaaService),我的命名空间有一个services attr,其中包含我要运行的所有服务类。
【问题讨论】:
-
后解析检查将是最简单的,因为你们都想处理无和重复。尝试在
argparse内执行此操作不会获得额外积分。