使用Python的optparse模块,如何创建一个带有可变数量参数的选项?

时间:2021-11-28 05:18:01

With Perl's Getopt::Long you can easily define command-line options that take a variable number of arguments:

使用Perl的Getopt :: Long,您可以轻松定义带有可变数量参数的命令行选项:

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

Is there a way to do this directly with Python's optparse module? As far as I can tell, the nargs option attribute can be used to specify a fixed number of option arguments, and I have not seen other alternatives in the documentation.

有没有办法直接使用Python的optparse模块?据我所知,nargs选项属性可用于指定固定数量的选项参数,我没有在文档中看到其他替代方法。

6 个解决方案

#1


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).

我相信optparse不支持你需要的东西(不是直接的 - 你注意到,如果你愿意做一个回调的额外工作,你可以做到!)。您也可以使用第三方扩展argparse进行最简单的操作,它支持可变数量的参数(并且还添加了几个其他方便的功能)。

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.

这个URL文档argparse的add_argument - 传递nargs ='*'允许该选项接受零个或多个参数,'+'允许它接受一个或多个参数,等等。

#2


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.

这需要我花一点时间来弄清楚,但你可以使用回调操作来完成这个任务。在这个例子中,检查我如何抓取任意数量的args到“--file”标志。

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.

唯一的副作用是你将args放在列表而不是元组中。但这可以很容易地修复,对于我的特定用例,列表是可取的。

#3


My mistake: just found this Callback Example 6.

我的错误:刚刚发现了这个回调示例6。

#4


Wouldn't you be better off with this?

你不是更好吗?

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

#5


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.

我最近自己有这个问题:我在Python 2.6上,需要一个选项来获取可变数量的参数。我尝试使用Dave的解决方案,但发现如果没有明确地将nargs设置为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.

问题在于,默认情况下,add_options添加的新选项假定为nargs = 1,当nargs> 0时,OptionParser会弹出rargs项并在调用任何回调之前将它们赋值给value。因此,对于未指定nargs的选项,在调用回调时,rargs将始终为1。

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

这个回调可用于任意数量的选项,只需将callback_args作为要调用的函数而不是setattr。

#6


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 *

这是一种方法:将fileLst生成字符串作为字符串,然后使用http://docs.python.org/2/library/glob.html进行扩展,如果不转义,这可能无法正常工作

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

实际上,有一个更好的方法:python myprog.py -V -l 1000 /home/dominic/radar/*.json < - 如果这是你的命令行

parser, opts = parse_args()

解析器,opts = parse_args()

inFileLst = parser.largs

inFileLst = parser.largs

#1


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).

我相信optparse不支持你需要的东西(不是直接的 - 你注意到,如果你愿意做一个回调的额外工作,你可以做到!)。您也可以使用第三方扩展argparse进行最简单的操作,它支持可变数量的参数(并且还添加了几个其他方便的功能)。

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.

这个URL文档argparse的add_argument - 传递nargs ='*'允许该选项接受零个或多个参数,'+'允许它接受一个或多个参数,等等。

#2


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.

这需要我花一点时间来弄清楚,但你可以使用回调操作来完成这个任务。在这个例子中,检查我如何抓取任意数量的args到“--file”标志。

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.

唯一的副作用是你将args放在列表而不是元组中。但这可以很容易地修复,对于我的特定用例,列表是可取的。

#3


My mistake: just found this Callback Example 6.

我的错误:刚刚发现了这个回调示例6。

#4


Wouldn't you be better off with this?

你不是更好吗?

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

#5


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.

我最近自己有这个问题:我在Python 2.6上,需要一个选项来获取可变数量的参数。我尝试使用Dave的解决方案,但发现如果没有明确地将nargs设置为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.

问题在于,默认情况下,add_options添加的新选项假定为nargs = 1,当nargs> 0时,OptionParser会弹出rargs项并在调用任何回调之前将它们赋值给value。因此,对于未指定nargs的选项,在调用回调时,rargs将始终为1。

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

这个回调可用于任意数量的选项,只需将callback_args作为要调用的函数而不是setattr。

#6


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 *

这是一种方法:将fileLst生成字符串作为字符串,然后使用http://docs.python.org/2/library/glob.html进行扩展,如果不转义,这可能无法正常工作

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

实际上,有一个更好的方法:python myprog.py -V -l 1000 /home/dominic/radar/*.json < - 如果这是你的命令行

parser, opts = parse_args()

解析器,opts = parse_args()

inFileLst = parser.largs

inFileLst = parser.largs