8

次のようなPythonでコマンドラインを解析しようとしています:

$ ./command -o option1 arg1 -o option2 arg2 arg3

つまり、コマンドは無制限の数の引数を取り、各引数の前に、-oその引数に特に関連するオプションをオプションで付けることができます。これを「接頭表記」と呼んでいると思います。

Bourne シェルでは、次のようなことを行います。

while test -n "$1"
do
    if test "$1" = '-o'
    then
        option="$2"
        shift 2
    fi
    # Work with $1 (the argument) and $option (the option)
    # ...
    shift
done

Bash のチュートリアルなどを見回すと、これは受け入れられているイディオムのように思われるので、Bash はこの方法でコマンドライン引数を操作するように最適化されていると思います。

このパターンを Python で実装しようとして、最初に推測したのは を使用することでしたpop()。これは基本的にスタック操作であるためです。sys.argvしかし、引数のリストが間違った順序であり、キューのように処理する必要があるため (つまり、左からポップ)、これは Python ではうまく機能しないと思います。Python でキューとして使用するためにリストが最適化されていないことを読みました。

したがって、私の考えは次のとおりです。 a に変換argvしてcollections.deque使用するpopleft()、逆にargv使用reverse()して使用するpop()、または int リストのインデックス自体を操作するだけです。

これを行うためのより良い方法を知っている人はいますか?

4

6 に答える 6

7

別のstdlibモジュール:argparse

p = argparse.ArgumentParser()
p.add_argument('-o', action='append')
for i in range(1, 4): p.add_argument('arg%d' % i)
args = p.parse_args('-o option1 arg1 -o option2 arg2 arg3'.split())
print args
# -> Namespace(arg1='arg1', arg2='arg2', arg3='arg3', o=['option1', 'option2'])
于 2010-05-14T07:09:58.253 に答える
7

できるよ

argv.pop(0)

最初の要素を取り出して返します。とはいえ、それはおそらく非効率的です。多分。argv内部でどのように実装されているかわかりません。(繰り返しになりますが、効率がそれほど重要である場合、なぜ Python を使用しているのですか?)

ただし、より Pythonic な解決策は、要素をポップせずにリストを反復処理することです。そのようです:

o_flag = False
for a in argv:
    if a == '-o':
        o_flag = True
        continue
    # do whatever
    o_flag = False

optparseまた、モジュールは言及に値すると思います。これは、Python プログラムでオプションと引数を処理するための非常に標準的なものですが、完全に機能するソリューションが既にいくつかあるため、このタスクにはやり過ぎかもしれません。

于 2010-05-14T03:39:37.477 に答える
7

Bourne/Bash の "shift" に相当する Python 機能は、sys をインポートしてから、sys.argv[1:] を変数 ("args" など) に割り当てることで実現できます。次に、args = args[1:] を使用して左に 1 回シフトするか、より大きな数値を使用して複数回シフトすることができます。引数のインデックスは 1 ではなく 0 から始まります。上記の例は次のようになります。

import sys
args = sys.argv[1:]
while len(args):
    if args[0] == '-o':
        option = args[1]
        args = args[2:] # shift 2
    # Work with args[0] (the argument) and option (the option)
    # ...
    args = args[1:] # shift
于 2014-04-14T09:45:55.983 に答える
3

何かのようなもの:

for arg in sys.argv[1:]:
  # do something with arg

あなたのためにうまくいくはずです。非常に多くの引数を想定している場合を除き、私は最も単純なコードを選びます (そしてパフォーマンスについてあまり心配しません)。argv[1:] は、スクリプトの名前になる最初の argv 値を無視します。

于 2010-05-14T03:45:01.910 に答える
2

車輪を再発明する必要はありませんgetopt。モジュールはまさにそのために設計されています。それがニーズに合わない場合は、optparseより柔軟ですが、より複雑なモジュールを試してください。

于 2010-05-14T04:23:05.377 に答える