web-dev-qa-db-ja.com

argparseとpythonで引数として辞書を受け入れる

Argparseでtype = dictの引数を受け入れようとしていますが、入力に関係なく無効なdict値のエラーが発生します。

#!/usr/bin/env python

import argparse

MYDICT = {'key': 'value'}

parser = argparse.ArgumentParser()
parser.add_argument("-m", "--mydict", action="store",
                    required=False, type=dict,
                    default=MYDICT)

args = parser.parse_args()

print args.mydict

これは、辞書をスクリプトに渡そうとするとどうなるかです。

./argp.py -m "{'key1': 'value1'}"
usage: argp.py [-h] [-m MYDICT]
argp.py: error: argument -m/--mydict: invalid dict value: "{'key1': 'value1'}"

文書を見ると、これは可能だと思います。

http://docs.python.org/dev/library/argparse.html

「in演算子をサポートするオブジェクトはすべて選択値として渡すことができるため、dictオブジェクト、setオブジェクト、カスタムコンテナーなどはすべてサポートされています。」

41
user2745896

文字列から辞書への変換関数が存在しないため、コマンドラインで辞書を引数として渡すことはできないと思います([〜#〜] edit [〜# 〜]:ハックは可能です、以下を参照)。本質的にpythonに指示することは:

dict("{'key1': 'value1'}")

pythonコンソールで試してみると機能しません。

フレーズ:

"in演算子をサポートするオブジェクトはすべて選択値として渡すことができるため、dictオブジェクト、setオブジェクト、カスタムコンテナなどがすべてサポートされます。"

参照するのはchoices引数で、add_argument関数で渡すことができます-type引数ではありません。

あなたの最善の策は、おそらく引数を文字列として受け入れてから、Pythonの json 機能を使用して変換することです:

parser.add_argument('-m', '--my-dict', type=str)
args = parser.parse_args()

import json
my_dictionary = json.loads(args.my_dict)

その後、文字列の形で辞書を渡すことができます。 pythonコンソールでjsonエンコーダー/デコーダーを試してみて、動作を確認できます。

>>>json.loads('{"value1":"key1"}')
{u'value1': u'key1'}

[〜#〜] edit [〜#〜]:hpauljは、を「ハック」できることを指摘してくれましたtypeパラメーターを渡すことによりjson.loads

import json
parser.add_argument('-d', '--my-dict', type=json.loads)
args = parse.parse_args()

mydict = args.my_dict  # Will return a dictionary

内部的にargparseが引数を変換する関数としてパラメータ値を使用するだけなので、これが実際に機能する理由は非常に興味深いです。つまり、type = intの場合はint(arg)を使用し、type = json.loadsの場合はjson.loads(arg)を使用します

これはまた、必要に応じて、入力する引数として単一のパラメータを受け取る関数を渡し、カスタム変換を実行できることを意味します:)

57