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

命令行如下所示,顺序如下:

来自有限集合的至少一项操作:cleansandpaintand 这个词是语法糖,以后忽略 一个任意的家具名称 从一组有限的颜色中选择一个:bluewhitered 有限集中的单个可选处理选项:vintage,rusheco

我已经用下面的 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` 参数中间吃掉任意字符串的主要内容,如果未能解决你的问题,请参考以下文章

argparse之add_argument() 方法

使用 unittest 测试 argparse - 退出错误

argparse 位置多项选择默认子集:无效选择

python的命令行参数处理

argparse 仅在位置参数之前解析

在 Argparse 中使用多个相同的参数