12

任意のコマンド ライン引数を受け取り、それらを Python 関数に渡すアプリケーションを作成しています。

$ myscript.py --arg1=1 --arg2=foobar --arg1=4

そして myscript.py 内:

import sys
argsdict = some_function(sys.argv)

次のようになりargsdictます。

{'arg1': ['1', '4'], 'arg2': 'foobar'}

これを行うライブラリがどこかにあると確信していますが、何も見つかりません。

編集: argparse/getopt/optparse は私が探しているものではありません。これらのライブラリは、呼び出しごとに同じインターフェースを定義するためのものです。任意の引数を処理できる必要があります。

argparse/optparse/getopt にこれを行う機能がない限り...

4

7 に答える 7

3

argparseストレッチではありますが、を使用した例を次に示します。私はこれを完全な解決策とは呼びませんが、むしろ良いスタートです。

class StoreInDict(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        d = getattr(namespace, self.dest)
        for opt in values:
            k,v = opt.split("=", 1)
            k = k.lstrip("-")
            if k in d:
                d[k].append(v)
            else:
                d[k] = [v]
        setattr(namespace, self.dest, d)

# Prevent argparse from trying to distinguish between positional arguments
# and optional arguments. Yes, it's a hack.
p = argparse.ArgumentParser( prefix_chars=' ' )

# Put all arguments in a single list, and process them with the custom action above,
# which convertes each "--key=value" argument to a "(key,value)" tuple and then
# merges it into the given dictionary.
p.add_argument("options", nargs="*", action=StoreInDict, default=dict())

args = p.parse_args("--arg1=1 --arg2=foo --arg1=4".split())
print args.options
于 2012-10-13T14:09:15.827 に答える
3

次のようなものを使用できます。

myscript.py

import sys
from collections import defaultdict

d=defaultdict(list)
for k, v in ((k.lstrip('-'), v) for k,v in (a.split('=') for a in sys.argv[1:])):
    d[k].append(v)

print dict(d)

結果:

C:\>python myscript.py  --arg1=1 --arg2=foobar --arg1=4
{'arg1': ['1', '4'], 'arg2': ['foobar']}

注: 値は常にリストになりますが、これはより一貫性があると思います。最終的な辞書を本当にしたい場合

{'arg1': ['1', '4'], 'arg2': 'foobar'}

その後、あなたはただ走ることができます

for k in (k for k in d if len(d[k])==1):
    d[k] = d[k][0]

その後。

于 2012-10-09T20:19:44.123 に答える
1

これは私が今日使用したものです。

--key=val--key-key-key val

def clean_arguments(args):
    ret_args = defaultdict(list)

    for index, k in enumerate(args):
        if index < len(args) - 1:
            a, b = k, args[index+1]
        else:
            a, b = k, None

        new_key = None

        # double hyphen, equals
        if a.startswith('--') and '=' in a:
            new_key, val = a.split('=')

        # double hyphen, no equals
        # single hyphen, no arg
        elif (a.startswith('--') and '=' not in a) or \
                (a.startswith('-') and (not b or b.startswith('-'))):
            val = True

        # single hypen, arg
        elif a.startswith('-') and b and not b.startswith('-'):
            val = b

        else:
            if (b is None) or (a == val):
                continue

            else:
                raise ValueError('Unexpected argument pair: %s, %s' % (a, b))

        # santize the key
        key = (new_key or a).strip(' -')
        ret_args[key].append(val)

    return ret_args
于 2015-12-04T20:58:19.727 に答える
1

このようなもの?

import sys

argsdict = {}

for farg in sys.argv:
    if farg.startswith('--'):
        (arg,val) = farg.split("=")
        arg = arg[2:]

        if arg in argsdict:
            argsdict[arg].append(val)
        else:
            argsdict[arg] = [val]     

指定とは少し異なりますが、値は常にリストです。

于 2012-10-09T20:12:37.803 に答える
1

..次の場合に、なぜ(多数の) ホイールを書き直そうとしているのですか?

?

編集:

あなたの編集に応えて、optparse/argparse (後者は >=2.7 でのみ利用可能) は、一貫したインターフェイスを維持しながら、ニーズに合わせて拡張するのに十分な柔軟性があります (たとえば、ユーザーは--arg=value--arg value-a valueおよびの両方を使用できることを期待しています)。-avalueなど.既存のライブラリを使用する場合、これらすべての構文のサポートについて心配する必要はありません)。

于 2012-10-09T20:27:51.447 に答える
0

またはこのようなもの)申し訳ありませんが、これがばかげている場合、私は初心者です:)

$ python3 Test.py a 1 b 2 c 3

import sys

def somefunc():
    keys = []
    values = []
    input_d = sys.argv[1:]

    for i in range(0, len(input_d)-1, 2):
        keys.append(input_d[i])
        values.append(input_d[i+1])

    d_sys = dict(zip(keys, values))

somefunc()
于 2018-10-01T18:20:27.150 に答える
-1

適切なコマンドライン解析ライブラリではなく、本当に独自のものを書きたい場合は、入力に対して次のようにします。

dict(map(lambda x: x.lstrip('-').split('='),sys.argv[1:]))

「=」なしで引数をキャッチするために何かを追加する必要があります。

于 2012-10-09T20:13:32.040 に答える