私はPythonの初心者です。
ArgparseとJSONを一緒に使用できるかどうか知りたかったのです。たとえば、変数がありますp,q,r
私はそれらをargparseに-として追加することができます
parser.add_argument('-p','--param1',help='x variable', required=True)
parser.add_argument('-q','--param2',help='y variable', required=True)
parser.add_argument('-r','--param3',help='z variable', required=True)
ここで、JSONファイルから同じ変数を読み取りたいとしましょう。それは可能ですか?そのため、コマンドラインまたはJSONファイルから値を入力できました。
JSON入力ファイル-
{
"testOwner": "my name",
"tests": [
"test1",
"test2",
"test3"
],
"testParameters": {
"test1": {
"param1": "0",
"param2": "20",
"param3" : "True"
},
"test2": {
"param1": "cc"
}
}
}
parse_args
のargs
名前空間は、次のコマンドで辞書に変換できます。
argparse_dict = vars(args)
JSON値も辞書にあり、たとえばjson_dict
です。選択した値を1つのディクショナリから別のディクショナリにコピーするか、スケール全体を更新できます。
argparse_dict.update(json_dict)
このようにして、json_dict
値はargparse値を上書きします。
両方を保持する場合は、異なる引数(キー)名を使用するか、値をリストにする必要があります。リストは追加または拡張できます。 nargs
で正しいargparse
値を使用することから始めて、これにはもう少し作業が必要です。
改訂されたparser
は、テスト入力を使用して生成します。
In [292]: args=parser.parse_args('-p one -q two -r three'.split())
In [293]: args
Out[293]: Namespace(param1='one', param2='two', param3='three')
In [295]: args_dict = vars(args)
In [296]: args_dict
Out[296]: {'param1': 'one', 'param2': 'two', 'param3': 'three'}
JSON文字列を解析すると(json.loads
?)、次のような辞書が生成されます。
In [317]: json_dict
Out[317]:
{'testOwner': 'my name',
'testParameters': {'test1': {'param1': '0', 'param2': '20', 'param3': 'True'},
'test2': {'param1': 'cc'}},
'tests': ['test1', 'test2', 'test3']}
ディスプレイをIpythonセッションに貼り付けて作成しましたが、JSONローダーでも同じことが作成されると思います
Argparse値は次のように追加できます。
In [318]: json_dict['testParameters']['test3']=args_dict
In [319]: json_dict
Out[319]:
{'testOwner': 'my name',
'testParameters': {'test1': {'param1': '0', 'param2': '20', 'param3': 'True'},
'test2': {'param1': 'cc'},
'test3': {'param1': 'one', 'param2': 'two', 'param3': 'three'}},
'tests': ['test1', 'test2', 'test3']}
ここでは、それを3番目のtest
セットとして追加し、(偶然に)tests
リストから名前を取得しました。 json_dict['testParameters']['test2']=args_dict
は、test2
の値を置き換えます。
'test2'の未定義の値にargs値を追加する1つの方法は次のとおりです。
In [320]: args_dict1=args_dict.copy()
In [322]: args_dict1.update(json_dict['testParameters']['test2'])
In [324]: json_dict['testParameters']['test2']=args_dict1
In [325]: json_dict
Out[325]:
{'testOwner': 'my name',
'testParameters': {'test1': {'param1': '0', 'param2': '20', 'param3': 'True'},
'test2': {'param1': 'cc', 'param2': 'two', 'param3': 'three'},
'test3': {'param1': 'one', 'param2': 'two', 'param3': 'three'}},
'tests': ['test1', 'test2', 'test3']}
このバージョンのupdate
を使用して、JSONディクショナリの「cc」値を優先しました。
JSONファイルに次の形式のdictが含まれているとします。
d = {"name": ["-x", "--xvar"], "help": "Help message", "required": True}
パーサーを作成した後、次のようにdictを「解凍」できます。
parser = argparse.ArgumentParser()
parser.add_argument(*(d.pop("name")), **d)
# Put the 'name' as name/flag and then unpack the rest of
# the dict as the rest of the arguments
parser.parse_args("--xvar 12".split())
>>> Namespace(xvar='12')
ただし、これにより、メソッドの引数名に合うようにdictキーを維持する必要がありますadd_arguments
。また、action
、type
、choices
引数を使用するような、より高度な動作を使用する単純で単純な方法もありません。
また、使用するさまざまな引数を含めるために、dictの形式を変更する必要があります。 1つの解決策は、名前/フラグをタプルのdictのキーとして持つことであり、引数はdictになります。
d = {("-x", "--xvar"): {"help": "Help message for x", "required": True},
("-y", "--yvar"): {"help": "Help message for y", "required": True}}
for names, args in d.iteritems():
parser.add_argument(*names, **args) # Use a similar unpacking 'magic' as the first example
parser.parse_args("-x 12 --yvar 42".split())
>>> Namespace(xvar='12', yvar='42')
[〜#〜] edit [〜#〜]OPからのコメントを考えると、彼が望んでいるように見えます JSONファイルから取得したparse値。
d = {"-x": "12", "-y": "42"}
args = []
for item in d.items():
args.extend(item)
parser.parse_args(args)
>>> Namespace(xvar='12', yvar='42')
編集2
argparse
ドキュメントを見る この段落 多分いくらか関連性があります。