使用optparse的可选参数的命令行选项

时间:2014-07-24 12:01:48

标签: python optparse

我正在寻找一种使用optparse Python模块使用可选参数创建命令行选项的方法。

例如,有两个命令行:foobar -u -vfoobar -u USERNAME -v。虽然后者将USERNAME作为参数,但前者应检测到缺少参数并从环境变量或其他方式获取用户名,而不是将-v视为参数,而是将其作为选项。< / p>

我知道有可能使用append动作获取多个参数,但它至少需要一个参数。

有没有解决方案?

更新:

如果没有提供任何争议,为什么这个脚本不会起作用? 我也给了Default一些价值。不能用这样的东西吗?

#!/usr/bin/env python                                                                                                                                                             
from optparse import OptionParser

parser = OptionParser()
parser.add_option("-u", "--user", dest="in_dir",
                  help="write report to FILE", action= "store", default='USERNAME')

(options, args) = parser.parse_args()
if options.in_dir == 'USERNAME':
        print' argument supplied or taken from default '
else:
        print 'arugment supplied'

执行此文件时,我们得到了 ./options.py -f 用法:options.py [options]

options.py:error:-f选项需要参数

因为我在默认值中给出了一些值。为什么不能从那里获取这个价值呢?还有其他解决办法吗?

3 个答案:

答案 0 :(得分:1)

也许您可以在将sys.argv选项添加到解析器之前检查-u。如果sys.argv上的下一个元素(-u之后)不是用户名,则可以在解析之前将用户名插入列表中。类似下面的代码:

import sys
from optparse import OptionParser as OP
cmdLine = sys.argv
i = cmdLine.index('-u')
if (i+1) == len(cmdLine) or cmdLine[i+1] not in users:
    cmdLine.insert(i+1,userName)
p = OP()
p.add_option('-u',action='append')
p.parse_args(cmdLine[1:])

答案 1 :(得分:0)

AFAIK没有optparse模块的解决方案。从Python标准库中提取(与Python 2 2和3相同):

  

通常,给定选项要么带参数,要么不带参数。很多人都想要一个“可选的选项参数”功能,这意味着如果他们看到某些选项将采用参数,如果他们不这样做则不会。这有点争议,因为它使解析变得模糊:如果-a采用可选参数而-b是完全另一种选择,我们如何解释-ab?由于这种歧义,optparse不支持此功能。

对于明确支持此类要求的较新argparse模块,您可以获得更多好运。来自Python标准库的摘录argparse

  

add_argument()方法

  ArgumentParser.add_argument(name或flags ... [,action] [,nargs] [,const] [,default] [,type] [,choices] [,required] [,help] [,metavar] [,dest] )
  定义应如何解析单个命令行参数。每个参数在下面都有自己更详细的描述,但简而言之,它们是:
  ...
nargs - 应该使用的命令行参数的数量。
...

以及稍后的nargs说明:

  

&#39;&#39 ;.如果可能,将从命令行使用一个参数,并将其作为单个项生成。如果不存在命令行参数,则将生成默认值。

答案 2 :(得分:0)

optparse文档中有example通过callback执行类似操作。

如果歧义很容易理解,例如,因为可选参数是int,您可以使用基本上从SageMathsage-runtest脚本复制的以下内容。     

import optparse

def optional_argument(option, opt_str, value, parser, typ, default_arg):
    try:
        next_arg = typ(parser.rargs[0])
    except Exception:
        next_arg = default_arg
    else:
        parser.rargs.pop(0)
    setattr(parser.values, option.dest, next_arg)

parser = optparse.OptionParser()
parser.add_option('-n',
    '--number',
    dest='n',
    default=-1,
    action="callback",
    callback=optional_argument,
    callback_args=(int, -2),
    nargs=0)

有了这个,你得到:

>>> parser.parse_args()
(<Values at ...: {'n': -1}>, [])
>>> parser.parse_args(['-n'])
(<Values at ...: {'n': -2}>, [])
>>> parser.parse_args(['-n', 42])
(<Values at ...: {'n': 42}>, [])

请注意,您需要在文档中明确提及可选参数; optparse,呈现帮助,好像这个参数没有参数:

>>> parser.print_help()
...
Options:
  -h, --help    show this help message and exit
  -n, --number