使用 getopt/optparse 处理一个选项的多个值?

发布于 2024-10-01 01:03:50 字数 472 浏览 6 评论 0原文

是否可以使用 getopt 或 optparse 获取一个选项的多个值,如下例所示:

./hello_world -c arg1 arg2 arg3 -b arg4 arg5 arg6 arg7

请注意,每个选项(-c、-b)的实际值的数量可以是 1 或 100。我不知道想要使用: ./hello_world -c "arg1 arg2 arg3" -b "arg4 arg5 arg6 arg7"

在我看来,这可能是不可能的(并且可能违反了 POSIX),如果我',请纠正我我错了。

我见过一些示例,其中可以收集行末尾的所有非选项 (./hello_world -c arg1 -b arg1 arg2 arg3)...但不适用于多个中的第一个选项。

我希望我的应用程序能够在具有不同 Python 版本的各种平台上运行,因此我没有查看 argparser。

Is it possible to fetch multiple values for one option using getopt or optparse, as shown in the example below:

./hello_world -c arg1 arg2 arg3 -b arg4 arg5 arg6 arg7

Please note that the number of actual values for each option (-c, -b) could be either 1 or 100. I do not want to use:
./hello_world -c "arg1 arg2 arg3" -b "arg4 arg5 arg6 arg7"

It seems to me that this may not be possible (and perhaps in violation of POSIX), please correct me if I'm wrong.

I've seen examples where all the non-options at the end of the line (./hello_world -c arg1 -b arg1 arg2 arg3) can be gathered... but not for the first of multiple option.

I'd like my app to work on a wide range of platforms with different Python versions, so I've not looked at argparser.

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

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

发布评论

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

评论(7

北陌 2024-10-08 01:03:50

是的,可以用 optparse 来完成。

这是一个示例:

./test.py --categories=aaa --categories=bbb --categories ccc arg1 arg2 arg3

打印:

arguments: ['arg1', 'arg2', 'arg3']
options: {'categories': ['aaa', 'bbb', 'ccc']}

下面是完整的工作示例:

#!/usr/bin/env python

import os, sys
from optparse import OptionParser
from optparse import Option, OptionValueError

VERSION = '0.9.4'

class MultipleOption(Option):
    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            values.ensure_value(dest, []).append(value)
        else:
            Option.take_action(self, action, dest, opt, value, values, parser)


def main():
    PROG = os.path.basename(os.path.splitext(__file__)[0])
    long_commands = ('categories')
    short_commands = {'cat':'categories'}
    description = """Just a test"""
    parser = OptionParser(option_class=MultipleOption,
                          usage='usage: %prog [OPTIONS] COMMAND [BLOG_FILE]',
                          version='%s %s' % (PROG, VERSION),
                          description=description)
    parser.add_option('-c', '--categories', 
                      action="extend", type="string",
                      dest='categories', 
                      metavar='CATEGORIES', 
                      help='comma separated list of post categories')

    if len(sys.argv) == 1:
        parser.parse_args(['--help'])

    OPTIONS, args = parser.parse_args()
    print "arguments:", args
    print "options:", OPTIONS

if __name__ == '__main__':
    main()

更多信息请访问 http://docs。 python.org/library/optparse.html#adding-new-actions

Yes, it can be done with optparse.

This is an example:

./test.py --categories=aaa --categories=bbb --categories ccc arg1 arg2 arg3

which prints:

arguments: ['arg1', 'arg2', 'arg3']
options: {'categories': ['aaa', 'bbb', 'ccc']}

Full working example below:

#!/usr/bin/env python

import os, sys
from optparse import OptionParser
from optparse import Option, OptionValueError

VERSION = '0.9.4'

class MultipleOption(Option):
    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            values.ensure_value(dest, []).append(value)
        else:
            Option.take_action(self, action, dest, opt, value, values, parser)


def main():
    PROG = os.path.basename(os.path.splitext(__file__)[0])
    long_commands = ('categories')
    short_commands = {'cat':'categories'}
    description = """Just a test"""
    parser = OptionParser(option_class=MultipleOption,
                          usage='usage: %prog [OPTIONS] COMMAND [BLOG_FILE]',
                          version='%s %s' % (PROG, VERSION),
                          description=description)
    parser.add_option('-c', '--categories', 
                      action="extend", type="string",
                      dest='categories', 
                      metavar='CATEGORIES', 
                      help='comma separated list of post categories')

    if len(sys.argv) == 1:
        parser.parse_args(['--help'])

    OPTIONS, args = parser.parse_args()
    print "arguments:", args
    print "options:", OPTIONS

if __name__ == '__main__':
    main()

More information at http://docs.python.org/library/optparse.html#adding-new-actions

酸甜透明夹心 2024-10-08 01:03:50

尽管其他评论声称,这对于普通的 optparse 来说是可能的,至少从 python 2.7 开始是这样。你只需要使用action="append"。从 docs 中:

parser.add_option("-t", "--tracks", action="append", type="int")

如果在命令行上看到 -t3,则 optparse 的作用相当于

options.tracks = []
options.tracks.append(int("3"))

: ,稍后,看到 --tracks=4 ,它确实:

options.tracks.append(int("4"))

Despite the claims of the other comments, this is possible with vanilla optparse, at least as of python 2.7. You just need to use action="append". From the docs:

parser.add_option("-t", "--tracks", action="append", type="int")

If -t3 is seen on the command-line, optparse does the equivalent of:

options.tracks = []
options.tracks.append(int("3"))

If, a little later on, --tracks=4 is seen, it does:

options.tracks.append(int("4"))
颜漓半夏 2024-10-08 01:03:50

抱歉来晚了,但我刚刚使用 nargs 标志通过 optparse 解决了这个问题。

parser.add_option('-c','--categories', dest='Categories', nargs=4 )

http://docs.python.org/2/library/optparse .html#optparse.Option.nargs

还值得注意的是,argparse(由 unutbu 建议)现在是标准 python 发行版的一部分,而 optparse 已被弃用。

Sorry to come late to the party but I just solved this with optparse using the nargs flag.

parser.add_option('-c','--categories', dest='Categories', nargs=4 )

http://docs.python.org/2/library/optparse.html#optparse.Option.nargs

It is also worth noting, that argparse (suggested by unutbu) is now part of the standard python distribution while optparse is deprecated.

始终不够 2024-10-08 01:03:50

另一种选择是定义一个分隔符并在本地处理它,就像 mount 命令中的选项一样。

例如,如果 , 可以用作分隔符:

...
args, _ = getopt.getopt(sys.argv[1:],'b:')
for flag, arg in args:
  if flag=='-b': all_arguments = arg.split(',')
...

$ ./test -b opt1,opt2,opt3

空格也一样!但是你的用户必须正确引用它。

$ ./test -b 'opt1 opt2 opt3'

Another option would be to define a separator and process it locally, like the options in the mount command.

For example, if , can be used as a separator:

...
args, _ = getopt.getopt(sys.argv[1:],'b:')
for flag, arg in args:
  if flag=='-b': all_arguments = arg.split(',')
...

$ ./test -b opt1,opt2,opt3

Same for space! But then your users have to quote it properly.

$ ./test -b 'opt1 opt2 opt3'
删除会话 2024-10-08 01:03:50

getopt 和 optparse 都不支持开箱即用。此外,在默认(GNU)模式下,附加参数将被视为散布参数,即在处理结束时可用作剩余参数。

惯例是要求重复提及相同的论点,即

./hello_world -c arg1 -c arg2 -c arg3 -b arg4 -b arg5 -b arg6 -b arg7

这将得到支持。

如果你绝对想让它按照你指定的方式工作(即 -b 和 -c 都延伸到下一个 - 参数或参数列表的末尾),那么你可以基于 optparse 来破解一些东西。继承自OptionParser,并覆盖_process_short_opts。如果这是您的选择之一,请在子类中处理它,否则转发到基类。

Neither getopt nor optparse support this out of the box. In addition, in the default (GNU) mode, the additional arguments would be treated as interspersed args, i.e. become available as left-over arguments at the end of the processing.

The convention would be to require repeated mentioning of the same argument, i.e.

./hello_world -c arg1 -c arg2 -c arg3 -b arg4 -b arg5 -b arg6 -b arg7

This is will supported.

If you absolutely want to get it work the way you specify (i.e. both -b and -c extend until the next - argument or the end of the argument list), then you can hack something together based on optparse. Inherit from OptionParser, and override _process_short_opts. If it's one of your options, process it in the subclass, else forward to the base class.

荆棘i 2024-10-08 01:03:50

您可以使用 Python2.7 附带的 argparse 中的 nargs 参数来执行此操作,并且可下载 此处

我认为这是对 argparse 添加的改进之一,而 optparse 中没有。因此,不幸的是,我认为没有一个好的方法可以使用 optparsegetopt (后者更旧)来处理这个问题。

一个快速而肮脏的解决方案可能是放弃 optparse/getop/argparse 并自己解析 sys.argv 。

或者,朝相反的方向走,您可能会考虑将 argparse (~88K) 的冻结副本(重命名为 argparse_static)与您的程序一起打包,并且
像这样导入它:

try:
    import argparse
except ImportError:
    import argparse_static as argparse

这样,如果安装了,程序将使用 argparse,如果没有安装,则使用 argparse_static。最重要的是,随着 argparse 成为标准,您不必重写太多代码。

You can do this with the nargs parameter in argparse which comes with Python2.7, and downloadable here.

I think it is one of the improvements added to argparse which is not in optparse. So, unfortunately, I don't think there is a nice way to handle this with optparse or getopt (which is even older).

A quick and dirty solution might be to forgo optparse/getop/argparse and just parse sys.argv yourself.

Or, going in the opposite direction, you might consider packaging a frozen copy of argparse (~88K) (renamed something like argparse_static) with your program, and
importing it like this:

try:
    import argparse
except ImportError:
    import argparse_static as argparse

That way, the program will use argparse if it is installed, and will use argparse_static if it is not. Best of all, you won't have to rewrite much code as argparse becomes standard.

孤檠 2024-10-08 01:03:50

更简单的一个:

make_option(
    "-c",
    "--city",
    dest="cities",
    action="append",
    default=[],
    help="specify cities",
)

附加操作是最简单的解决方案这个问题。

An easier one:

make_option(
    "-c",
    "--city",
    dest="cities",
    action="append",
    default=[],
    help="specify cities",
)

Append action is the easiest solution for this problem.

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