是否可以使用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。
答案 0 :(得分:14)
是的,可以使用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
的更多信息答案 1 :(得分:9)
尽管有其他评论的说法,但这可能是vanilla optparse,至少从python 2.7开始。你只需要使用action ="追加"。来自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"))
答案 2 :(得分:8)
很抱歉来参加聚会,但我刚用optparse使用nargs标志解决了这个问题。
parser.add_option('-c','--categories', dest='Categories', nargs=4 )
http://docs.python.org/2/library/optparse.html#optparse.Option.nargs
值得注意的是,argparse(由unutbu建议)现在是标准python发行版的一部分,而optparse已被弃用。
答案 3 :(得分:5)
您可以使用Python2.7附带的nargs
中的argparse
参数执行此操作,并可下载here。
我认为这是argparse
中添加的改进之一,而不是optparse
。所以,遗憾的是,我认为使用optparse
或getopt
(甚至更早)处理此问题的方法并不好。
快速而肮脏的解决方案可能是放弃optparse/getop/argparse
而只是自己解析sys.argv
。
或者,在相反的方向上,您可以考虑使用您的程序打包argparse(~88K)的冻结副本(重命名为argparse_static
),以及
像这样导入它:
try:
import argparse
except ImportError:
import argparse_static as argparse
这样,如果安装了程序,程序将使用argparse
,如果不是,则使用argparse_static
。最重要的是,当argparse
成为标准时,您不必重写太多代码。
答案 4 :(得分:5)
getopt和optparse都不支持开箱即用。此外,在默认(GNU)模式下,附加参数将被视为散布的args,即在处理结束时可用作剩余参数。
惯例是要求反复提及相同的论点,即
./hello_world -c arg1 -c arg2 -c arg3 -b arg4 -b arg5 -b arg6 -b arg7
这将得到支持。
如果你绝对希望以你指定的方式使它工作(即-b和-c都延伸到下一个参数或参数列表的结尾),那么你可以根据optparse一起破解一些东西。从OptionParser继承,并覆盖_process_short_opts。如果它是您的选项之一,请在子类中处理它,否则转发到基类。
答案 5 :(得分:4)
另一种选择是定义一个分隔符并在本地处理它,就像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'
答案 6 :(得分:3)
更容易:
make_option(
"-c",
"--city",
dest="cities",
action="append",
default=[],
help="specify cities",
)
Append action是解决此问题的最简单方法。