以下の例に示すように、getoptまたはoptparseを使用して1つのオプションの複数の値をフェッチすることは可能ですか?
./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は調べていません。
はい、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 をご覧ください。
他のコメントの主張にもかかわらず、これは、少なくともpython 2.7の時点で、Vanilla optparseで可能です。必要なのは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"))
パーティーに遅れて申し訳ありませんが、argsフラグを使用して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は非推奨になりました。
これを行うには、Python2.7に付属するnargs
のargparse
パラメータを使用し、ダウンロード可能 here を使用します。
argparse
にはないoptparse
に追加された改善点の1つだと思います。したがって、残念ながら、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
が標準になるため、多くのコードを書き直す必要がありません。
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をオーバーライドします。それがオプションの1つである場合は、サブクラスで処理します。それ以外の場合は、基本クラスに転送します。
別のオプションは、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'
より簡単なもの:
make_option(
"-c",
"--city",
dest="cities",
action="append",
default=[],
help="specify cities",
)
追加アクション は、この問題の最も簡単な解決策です。