With Python's optparse module, how do you create an option that takes a variable number of arguments?

百般思念 提交于 2019-12-03 11:08:46

I believe optparse does not support what you require (not directly -- as you noticed, you can do it if you're willing to do all the extra work of a callback!-). You could also do it most simply with the third-party extension argparse, which does support variable numbers of arguments (and also adds several other handy bits of functionality).

This URL documents argparse's add_argument -- passing nargs='*' lets the option take zero or more arguments, '+' lets it take one or more arguments, etc.

Dave Rawks

This took me a little while to figure out, but you can use the callback action to your options to get this done. Checkout how I grab an arbitrary number of args to the "--file" flag in this example.

from optparse import OptionParser,

def cb(option, opt_str, value, parser):
        args=[]
        for arg in parser.rargs:
                if arg[0] != "-":
                        args.append(arg)
                else:
                        del parser.rargs[:len(args)]
                        break
        if getattr(parser.values, option.dest):
                args.extend(getattr(parser.values, option.dest))
        setattr(parser.values, option.dest, args)

parser=OptionParser()
parser.add_option("-q", "--quiet",
        action="store_false", dest="verbose",
        help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
        action="callback", callback=cb, dest="file")

(options, args) = parser.parse_args()

print options.file
print args

Only side effect is that you get your args in a list instead of tuple. But that could be easily fixed, for my particular use case a list is desirable.

My mistake: just found this Callback Example 6.

Wouldn't you be better off with this?

foo.pl --files a.txt,b.txt,c.txt --verbose

I recently has this issue myself: I was on Python 2.6 and needed an option to take a variable number of arguments. I tried to use Dave's solution but found that it wouldn't work without also explicitly setting nargs to 0.

def arg_list(option, opt_str, value, parser):
    args = set()
    for arg in parser.rargs:
        if arg[0] == '-':
            break
        args.add(arg)
        parser.rargs.pop(0)
    setattr(parser.values, option.dest, args)

parser=OptionParser()
parser.disable_interspersed_args()
parser.add_option("-f", "--filename", action="callback", callback=arg_list,
                  dest="file", nargs=0)

(options, args) = parser.parse_args()

The problem was that, by default, a new option added by add_options is assumed to have nargs = 1 and when nargs > 0 OptionParser will pop items off rargs and assign them to value before any callbacks are called. Thus, for options that do not specify nargs, rargs will always be off by one by the time your callback is called.

This callback is can be used for any number of options, just have callback_args be the function to be called instead of setattr.

Here's one way: Take the fileLst generating string in as a string and then use http://docs.python.org/2/library/glob.html to do the expansion ugh this might not work without escaping the *

Actually, got a better way: python myprog.py -V -l 1000 /home/dominic/radar/*.json <- If this is your command line

parser, opts = parse_args()

inFileLst = parser.largs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!