ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python – 检测是否使用optparse或argparse多次指定了任何命令行选项

2019-07-04 05:43:36  阅读:284  来源: 互联网

标签:python argparse optparse


Python optparse通常允许用户多次指定一个选项,并默默地忽略所有选项但最后一个选项.例如,如果选项–foo的操作是store,而选项–flag的操作是store_const,store_true或store_false,则以下命令将是等效的:

my-command --foo=bar --foo=another --flag --foo=last --flag
my-command --flag --foo=last

(更新:默认情况下,argparse会做同样的事情.)

现在,我有很多选择,并且不止一次指定其中任何一个都没有意义.如果用户多次指定相同的选项,我想警告他们可能的错误.

检测多次指定选项的最优雅方法是什么?请注意,相同的选项可以使用简短形式,长形式和缩写长形式(因此-f, – foobar,–foob和–foo都是相同的选项).如果有可能在同时指定具有相同目标的多个选项时检测到这种情况会更好,因此如果用户同时指定了–quiet和–verbose,则可以给出警告,而两个选项都存储值进入同一目的地并有效地互相覆盖.

更新:为了更加用户友好,警告应该引用命令行中使用的确切选项名称.使用追加操作而不是存储是可能的,但是当我们检测到冲突时,我们无法说明导致它的选项(是-q和–verbose还是–quiet –quiet?).

不幸的是我坚持使用optparse并且不能使用argparse,因为我必须支持Python 2.6.

P. S.如果你知道一个只适用于argparse的解决方案,请发布它.虽然我尝试最小化外部依赖项的数量,但在Python 2.6下使用argparse仍然是一种选择.

解决方法:

我认为正确的方法是以某种方式“定义你的行动”.

例如,您可以使用操作callback并实现一个实现所需行为的函数.
您可以编写一个函数,首先检查目标是否已填充,如果已填充,则将重叠选项存储到列表中.
解析完成后,您应该检查这些列表是否为空,如果它们没有引发相应的异常.

另一种方法是定义自己的动作.你可以看看here

一个使用回调的小例子:

import sys
import functools
from optparse import OptionParser


bad_option = 'BAD OPTION'

def store(option, opt, value, parser, dest, val):
    """Set option's destination *dest* to *val*  if there are no conflicting options."""
    list_name = dest + '_options_list'
    try:
        # if this option is a conflict, save its name and set the value to bad_option
        getattr(parser.values, list_name).append(opt)
        setattr(parser.values, dest, bad_option)
    except AttributeError:
        # no conflicts, set the option value and add the options list
        setattr(parser.values, dest, val)
        setattr(parser.values, list_name, [opt])

store_true = functools.partial(store, val=True)
store_false = functools.partial(store, val=False)


parser = OptionParser()
parser.add_option('-v', '--verbose',
                  action='callback', callback=store_true,
                  help='Increase output verbosity',
                  callback_kwargs={'dest': 'verbose'})

parser.add_option('-q', '--quiet',
                  action='callback', callback=store_false,
                  help='Decrease output verbosity',
                  callback_kwargs={'dest': 'verbose'})

opts, args = parser.parse_args()

# detects all conflicting options for all destinations
found = False
for dest in ('verbose',):
    if getattr(opts, dest) == bad_option:
        conflicting_opts = ', '.join(getattr(opts, dest + '_options_list'))
        print('Conflicting options %s for destination %s'
              % (conflicting_opts, dest))
        found = True

if found:
    parser.print_usage()
    sys.exit(2)

并输出:

$python testing_optparse.py -v -q
Conflicting options -v, -q for destination verbose
Usage: prova_optparse.py [options]

可能最好在检测到冲突时引发OptionValueError,即使这样只能获得几个冲突的选项.如果要获取所有冲突的选项,则必须解析剩余的参数(在parser.rargs中).

标签:python,argparse,optparse
来源: https://codeday.me/bug/20190704/1374117.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有