jjzjj

python - Docopt:重复元素后的选项被解释为重复元素

coder 2023-08-23 原文

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

#!/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> 的值(value):

{'--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'],

这意味着您定义了一个 bool 值 --quantity参数和位置 quantity争论。两者无关……因此如下:

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

给出结果:

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

这不是您想要的……所以让我们回到您想要的:您说您想要一个参数,该参数采用两个值来定义最小值和可选的最大值。但我很遗憾地告诉你,这个确切的规则在 geptopt 中不再可能。 , argparsedocopt .

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

两个开关

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 (因为解析器将强制您至少提供一个)。但是你必须在描述中真正清楚地说明你的意思是如何使用它并给出一两个例子。

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

关于python - Docopt:重复元素后的选项被解释为重复元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21804165/

有关python - Docopt:重复元素后的选项被解释为重复元素的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  3. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  4. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  5. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  6. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  7. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  8. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  9. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  10. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

随机推荐