Python OptionParser允许选择类型选项有多个参数

Python OptionParser允许选择类型选项有多个参数,python,optionparser,Python,Optionparser,我在OptionParser中有一个选项,如下所示: foo_选项=['foo','bar','mac','win'] parser.add_选项('-t','-test',, type='choice', 行动='商店', dest='test', 选项=foo_选项, 默认值(='foo') 但是,我希望该选项能够接受多个选项(可以是逗号分隔的,或者允许>1参数)。只需设置nargs=2就可以传递多个参数,所以我假设这可以用于类型选择。我不知道如何对数量可变的NARG执行此操作 语法如下:

我在OptionParser中有一个选项,如下所示:

foo_选项=['foo','bar','mac','win']
parser.add_选项('-t','-test',,
type='choice',
行动='商店',
dest='test',
选项=foo_选项,
默认值(='foo')
但是,我希望该选项能够接受多个选项(可以是逗号分隔的,或者允许>1参数)。只需设置nargs=2就可以传递多个参数,所以我假设这可以用于类型选择。我不知道如何对数量可变的NARG执行此操作

语法如下:

./demo.py -t foo -o out.out
./demo.py -t foo,bar -o out.out

我曾尝试使用回调在逗号上拆分,但如果回调返回数组,则会出错,因为该选项是无效的选项“foo,bar”。这个错误是有道理的,但我不确定从这里该怎么办

def foo_callback(option, opt, value, parser):
  setattr(parser.values, option.dest, value.split(','))
试图采用nargs方法,我尝试实施

#/usr/bin/python
从optpasse导入OptionParser
def main():
parser=OptionParser()
foo_选项=['foo'、'bar'、'mac'、'win']
parser.add_选项('-t','-test',,
type='choice',
action='callback',
dest='test',
选项=foo_选项,
callback=vararg\u callback)
(options,args)=parser.parse_args()
打印选项
打印参数
def vararg_回调(选项、opt_str、值、解析器):
断言值为无
值=[]
def浮动(str):
尝试:
浮动(str)
返回真值
除值错误外:
返回错误
对于parser.rargs中的arg:
#停止--类似foo的选项
如果arg[:2]=“--”和len(arg)>2:
打破
#在-a上停止,但不要在-3或-3.0上停止
如果arg[:1]=“-”且len(arg)>1且不可浮动(arg):
打破
value.append(arg)
del parser.rargs[:len(值)]
setattr(parser.values,option.dest,value)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
这段代码介绍了一种实现可变数量NARG的方法。然而,我实现这一点的唯一方法是从我的选项中删除类型和选项(这违背了我正在尝试做的事情的目的)。如果我没有,我会得到的错误是:

[vagrant@machine a]$ ./demo.py -t foo
Traceback (most recent call last):
  File "./demo.py", line 43, in <module>
    main()
  File "./demo.py", line 14, in main
    (options, args) = parser.parse_args()
  File "/usr/lib64/python2.6/optparse.py", line 1394, in parse_args
    stop = self._process_args(largs, rargs, values)
  File "/usr/lib64/python2.6/optparse.py", line 1438, in _process_args
    self._process_short_opts(rargs, values)
  File "/usr/lib64/python2.6/optparse.py", line 1545, in _process_short_opts
    option.process(opt, value, values, self)
  File "/usr/lib64/python2.6/optparse.py", line 788, in process
    self.action, self.dest, opt, value, values, parser)
  File "/usr/lib64/python2.6/optparse.py", line 808, in take_action
    self.callback(self, opt, value, parser, *args, **kwargs)
  File "./demo.py", line 20, in vararg_callback
    assert value is None
AssertionError
[vagrant@machinea]$./demo.py-t foo
回溯(最近一次呼叫最后一次):
文件“/demo.py”,第43行,在
main()
文件“/demo.py”,第14行,主
(options,args)=parser.parse_args()
parse_args中的文件“/usr/lib64/python2.6/optparse.py”,第1394行
停止=自身。\处理\参数(大、小、值)
文件“/usr/lib64/python2.6/optparse.py”,第1438行,在进程参数中
自我评估过程短期选择(风险调整、价值)
文件“/usr/lib64/python2.6/optparse.py”,第1545行,在“进程”中
option.process(opt、value、value、self)
文件“/usr/lib64/python2.6/optparse.py”,第788行,正在处理中
self.action、self.dest、opt、value、value、parser)
文件“/usr/lib64/python2.6/optparse.py”,第808行,在take_action中
回调(self、opt、value、解析器、*args、**kwargs)
文件“/demo.py”,第20行,在vararg\u回调中
断言值为无
断言错误

只需使用
action='append',default=[]
而不是当前设置;无需自定义回调。
然后可以将倍数指定为:
-tfoo-tbar

如果你需要一个默认值,你可以事后再做;i、 e.类似于

test=options.test或['foo']

我认为您可以尝试从标准派生自己的选项类,以覆盖案例的标准检查:

from optparse import Option, OptionParser, OptionValueError

class MyOption(Option):
    def check_value(option, opt, value):
        for val in value.split(','):
            if val not in option.choices:
                choices = ", ".join(map(repr, option.choices))
                raise OptionValueError("option %s: invalid choice: %r (choose from %s)" % (opt, val, choices))
        return value

 parser = OptionParser(option_class=MyOption)
 foo_choices = ['foo', 'bar', 'mac', 'win'] 
 parser.add_option('-t', '--test',
          type='choice',
          dest='test',
          choices=foo_choices)


(options, args) = parser.parse_args()

print options
输出:

./test1.py -t foo,bar,mac
{'test': 'foo,bar,mac'}

可能重复到在上面链接中的一个答案中,您可以快速找到示例供参考,@C.B.我知道,但我现在仅限于Python 2.6。@pmod示例提供了类似“/demo.py-t foo-t bar”的格式,这不是我想要的附加样式。更不用说,这些示例没有使用“choice”类型选项。正如在另一条评论中提到的,我不希望用户重复-t多次。语法应该尽可能简单,所以我更喜欢将其保持为“-t foo bar”或“-t foo,bar”
./test1.py -t foo,bar,mac
{'test': 'foo,bar,mac'}