Docopt:重复元素之后的选项作为重复元素插入



我在简单的Python程序中使用docopt

#!/usr/bin/env python
"""
Farmers market
Usage:
farmersmarket.py buy -i <item> -q <quantity> [<quantity>] [-p <price>] [-dvh]
farmersmarket.py -d | --debug
farmersmarket.py -v | --version
farmersmarket.py -h | --help
Options:
-i --item         Item.
-q --quantity     Quantity.
-p --price        Price.
-d --debug        Show debug messages.
-h --help         Show this screen.
-v --version      Show version.
"""
from docopt import docopt
print docopt(__doc__)

如果我运行:

farmersmarket.py buy --item eggs --quantity 100 115 --price 0.25

预期的行为是以 0.25 的价格购买价值在 100 到 115 之间的随机数量的鸡蛋。至少在解释论点时,这是没有问题的。换句话说,docopt可以按预期获得所有内容:

{'--debug': False,
'--help': False,
'--item': True,
'--price': True,
'--quantity': True,
'--version': False,
'<item>': 'eggs',
'<price>': '0.25',
'<quantity>': ['100', '115'],
'buy': True}

然而,有时我不想买随机数量的鸡蛋,而是购买特定数量的鸡蛋。在这种情况下,--quantity选项仅接受一个参数:

farmersmarket.py buy --item eggs --quantity 471 --price 0.25

但这失败了,因为docopt--price 0.25解释为--quantity的重复元素并失去了<price>的值:

{'--debug': False,
'--help': False,
'--item': True,
'--price': True,
'--quantity': True,
'--version': False,
'<item>': 'eggs',
'<price>': None,
'<quantity>': ['471', '0.25'],
'buy': True}

如何在重复元素后获得其他选项?

实际上,您忘记将<price>参数添加到Options:描述部分;以下代码:

#!/usr/bin/env python
"""
Farmers market
Usage:
farmersmarket.py buy -i <item> -q <quantity> [<quantity>] [-p <price>] [-dvh]
farmersmarket.py -d | --debug
farmersmarket.py -v | --version
farmersmarket.py -h | --help
Options:
-i --item           Item.
-q --quantity       Quantity.
-p --price <price>  Price.
-d --debug          Show debug messages.
-h --help           Show this screen.
-v --version        Show version.
"""
from docopt import docopt
print docopt(__doc__)

正在按预期工作:

% farmersmarket.py buy --item eggs --quantity 100 --price 0.25
{'--debug': False,
'--help': False,
'--item': True,
'--price': '0.25',
'--quantity': True,
'--version': False,
'<item>': 'eggs',
'<quantity>': ['100'],
'buy': True}

编辑:

但实际上,你试图实现的目标是错误的。如果你看一下解析的参数,你会看到:

'--quantity': True,
[…]
'<quantity>': ['100'],

这意味着您定义了布尔--quantity参数和位置quantity参数。两者都不相关...因此,如下:

buy --items eggs --quantity --price 0.25 100 2 

给出结果:

'--quantity': True,
[…]
'<quantity>': ['100','2'],

这不是你想要的...因此,让我们回到您想要的内容:您说您想要一个参数,该参数采用两个值来定义最小值和可选最大值。但我很抱歉地告诉你,这个确切的规则在geptoptargparse比在docopt中更不可能。

解析完成后,解决方案将始终涉及一些逻辑,或者您需要更改解析参数的方式。所以我可以为你看到四个选项:

两个开关

Farmers market
Usage:
farmersmarket.py buy -i <item> -m <min> [-M <max>] [-p <price>] [-dvh]
farmersmarket.py -d | --debug
farmersmarket.py -v | --version
farmersmarket.py -h | --help
Options:
-i --item <item>                  Item.
-m --min <min>                    Minimal quantity.
-M --max <min>                    Maximal quantity.
-p --price <price>                Price.
-d --debug                        Show debug messages.
-h --help                         Show this screen.
-v --version                      Show version.  

在这里,最简单但我认为最好的解决方案是使用两种不同的选项来设置最大和最小边界。这是解析器可以处理{1,2}数量的参数以及实现它的唯一方法。

使用单个参数

让你真正与列表进行参数的最接近的方法是实际"玩"语法:

Farmers market
Usage:
farmersmarket.py buy -i <item> -q <quantity> [-p <price>] [-dvh]
farmersmarket.py -d | --debug
farmersmarket.py -v | --version
farmersmarket.py -h | --help
Options:
-i --item <item>                  Item.
-q --quantity <quantity>          Quantity: min[,max]
-p --price <price>                Price.
-d --debug                        Show debug messages.
-h --help                         Show this screen.
-v --version                      Show version.  

然后,您可以使用:

% farmersmarket.py buy --items eggs -q 100,2 --price 0.25

并通过以下方式获取最小值和最大值:if len(docopt(__doc__)['--quantity'].split(',')) == 2: qmin, qmax = docopt(__doc__)['--quantity'].split(',').

仅使用位置参数

最后,您的最后一个解决方案是仅使用位置参数:

Farmers market
Usage:
farmersmarket.py buy <item> <min_qty> [<max_qty>] [-p <price>] [-dvh]
farmersmarket.py -d | --debug
farmersmarket.py -v | --version
farmersmarket.py -h | --help
Options:
<item>              Item.
<min_qty>           Minimum quantity
<max_qty>           Maximum quantity
-p --price <price>  Price.
-d --debug          Show debug messages.
-h --help           Show this screen.
-v --version        Show version.  

然后当你调用时它起作用:

% farmersmarket.py buy eggs 100 2 -p 0.25

选项列表

但是看起来您想获取参数列表,而使用命令行选项实现此目的的唯一方法是重复选项-q 1 -q 2 -q 3…。要告诉 docopt 这就是你想要的,你需要在选项的参数后添加一个省略号:

Farmers market
Usage:
farmersmarket.py buy -i <item> -q <quantity>... [-p <price>] [-dvh]
farmersmarket.py -d | --debug
farmersmarket.py -v | --version
farmersmarket.py -h | --help
Options:
-i --item <item>                  Item.
-q --quantity <quantity>...       Quantity (-q min -q max)
-p --price <price>                Price.
-d --debug                        Show debug messages.
-h --help                         Show this screen.
-v --version                      Show version.  

然后你可以打电话:

% farmersmarket.py buy --items eggs -q 100 -q 2 --price 0.25 

但是,您必须检查该len(docopt(__doc__)['--quantity']) < 2(因为解析器将强制您至少提供一个)。但是,您必须在描述中明确说明您的意图如何使用它,并举一两个例子。

最后,我建议您使用选项列表以外的其他三个选项之一,因为它们使您更清楚地希望如何调用程序。

相关内容

  • 没有找到相关文章

最新更新