Argparse 在 `choice` 参数中间吃掉任意字符串
Posted
技术标签:
【中文标题】Argparse 在 `choice` 参数中间吃掉任意字符串【英文标题】:Argparse eats arbitrary strings in the middle of `choice` arguments 【发布时间】:2019-01-04 15:12:52 【问题描述】:我有一个程序必须接受这样的命令行:
python wood.py clean and paint chair red
命令行如下所示,顺序如下:
来自有限集合的至少一项操作:clean
、sand
或 paint
。 and
这个词是语法糖,以后忽略
一个任意的家具名称
从一组有限的颜色中选择一个:blue
、white
或 red
有限集中的单个可选处理选项:vintage
,rush
或 eco
我已经用下面的 Python 代码实现了它
import argparse
from pprint import pprint as pp
parser = argparse.ArgumentParser()
parser.add_argument('operations', metavar='operations', type=str, choices=['clean','sand','paint', 'and'], nargs="+")
parser.add_argument('furniture', metavar='furniture', type=str)
parser.add_argument('color', metavar='color', choices=['blue','white','red'], type=str)
parser.add_argument('handling', metavar='handling', type=str, choices=['rush','vintage','ecologic'], nargs="?")
args = parser.parse_args()
pp([op for op in args.operations if op != 'and'])
pp(args.furniture)
pp(args.color)
pp(args.handling)
它可以工作,但是当我在末尾添加可选的handling
参数时,argparse 会将家具(椅子)解释为一个操作。
> python wood.py clean and sand and paint chair red vintage
usage: wood.py [-h]
operations [operations ...] furniture [furniture ...] color
[handling]
wood.py: error: argument operations: invalid choice: 'chair' (choose from 'clean', 'sand', 'paint', 'and')
是什么让 argparse 认为选择参数后的任意字符串是该选择的一部分?
【问题讨论】:
它严格按照位置而不是值将字符串分配给参数。选择检查在分配之后进行。handling
对 0 个字符串感到满意,因此 operations
获得了其他两个不需要的所有内容。
最好自己解析sys.argv
。你会有更多的控制权。在这里,您过于依赖未针对此布局优化的argparse
详细信息。
最好将handling
设为标记参数。这清楚地标识了哪个字符串适用于该参数。有多个 '*+?' nargs
经常引起问题,因为每个问题都是“贪婪的”。
@hpaulj 你的评论“[argparse] is allocating strings to arguments strict on position”是正确的答案,贴出来我会接受的。
【参考方案1】:
argparse
很困惑,因为处理以h
开头,而h
用于help
。换个词或者用大写的H
parser.add_argument('Handling', metavar='handling', help='bam')
您稍后将不得不使用args.Handling
,因为metavar
只会更改帮助文本中的名称。
【讨论】:
好吧,反正不是在 Python 2.7 上。我用zzz
替换了handling
,我得到了同样的错误。
在 python 2.7 btw 中测试。
粘贴完整代码(我已经提供了一个可重现的小片段)。当我将 handling
替换为 zzz
时,我仍然收到错误:用法:argtest.py [-h] 操作 [操作 ...] 家具颜色 [zzz]
help
标志是“-h”。位置字符串不按值解析。以上是关于Argparse 在 `choice` 参数中间吃掉任意字符串的主要内容,如果未能解决你的问题,请参考以下文章