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

发布于 2024-07-24 22:42:24 字数 261 浏览 5 评论 0原文

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

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

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

掐死时间 2024-07-31 22:42:24

这花了我一些时间才弄清楚,但您可以使用选项的回调操作来完成此操作。 在此示例中,查看我如何将任意数量的参数获取到“--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

唯一的副作用是您将参数放在列表而不是元组中。 但这很容易解决,对于我的特定用例来说,需要一个列表。

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.

我不是你的备胎 2024-07-31 22:42:24

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

My mistake: just found this Callback Example 6.

皇甫轩 2024-07-31 22:42:24

我相信 optparse 不支持您所需要的(不是直接支持 - 正如您所注意到的,如果您愿意完成回调的所有额外工作,您就可以做到这一点!-)。 您还可以使用第三方扩展 argparse 最简单地完成此操作,该扩展确实支持变量数字参数(并且还添加了其他一些方便的功能)。

此网址记录了 argparse 的内容add_argument -- 传递 nargs='*' 让选项接受零个或多个参数,'+' 让选项接受一个或多个参数, ETC。

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.

路还长,别太狂 2024-07-31 22:42:24

有了这个你不是会过得更好吗?

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

Wouldn't you be better off with this?

foo.pl --files a.txt,b.txt,c.txt --verbose
你是我的挚爱i 2024-07-31 22:42:24

我自己最近也遇到了这个问题:我使用的是 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()

问题是,默认情况下,add_options 添加的新选项被假定为 nargs = 1,并且当 nargs > 时,它不会工作。 0 OptionParser 将从 rargs 中弹出项目,并在调用任何回调之前将它们分配给 value。 因此,对于未指定 nargs 的选项,在调用回调时,rargs 将始终关闭 1。

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

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.

半透明的墙 2024-07-31 22:42:24

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

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

, opts = parse_args()

inFileLst = parser.largs

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文