Python subprocessにて引数に辞書やリストを用いたい場合

 subprocessを用いてpythonスクリプトを実行したい状況があるとします。引数に、辞書やリストを設定したい場合は、一旦JSON文字列へ変換してから引数として渡します。
 下図中の上の行はpythonの辞書型の例です。これを、json.dumps()でJSON形式の文字列へ変換したのが下図中の下の行です。変数やシングルクォーテーションは、ダブルクォーテーションになります。

 このJSON文字列を引数として受け取ったサブのpythonスクリプトでは、json.loads()でpythonの辞書やリストへ戻して使用することになります。

▼メインのPythonスクリプトの例

import subprocess
import json

# サブプロセスへ渡したい辞書型のデータ
my_dict = {1: 'a', 2: 'b', 3: 'c'}
print('python dict ->', my_dict)

# JSON文字列へ変換する
json_dict = json.dumps(my_dict)
print('json dict ->', json_dict)

# サブプロセスを実行するコマンドリスト
cmd_list = ['python', 'sub_script.py', json_dict]

# サブプロセスでコマンドを実行する
try:
    result = subprocess.run(
        cmd_list,
        shell = False, # シェルを介して直接実行するかどうか。Trueの場合はコマンド引数をリストではなくて文字列で渡す。
        check = True, # 実行されたプロセスが正常に終了したかどうかを確認する
        capture_output = True, # 標準出力および標準エラー出力をキャプチャするかどうか
        text = True, # 標準入力(input引数)や標準出力(stdoutおよびstderr引数)がテキストとして扱われる
    )
    print('Job submitted successfully')
    print(result.stdout) # 標準出力を取得して、print文で表示
    
# 外部プロセスでエラーが生じた場合に、その内容を表示する
except subprocess.CalledProcessError as e:
    print(f'Error submitting job. Exit code: {e.returncode}')
    print(f"Output: {e.stdout}")
    print(f"Error Output: {e.stderr}")

▼サブのPythonスクリプト

import sys
import json

# JSON文字列を受け取る
json_dict = sys.argv[1]

# JSON文字列をPythonの辞書型へ変換
my_dict = json.loads(json_dict)

# 辞書として使える
for key, val in my_dict.items():
    print(key, val)

 ※使用環境によっては、sys.argvで受け取った文字列が崩れる場合があります。例えば、辞書の要素内のダブルクォーテーションがなかったりです。運悪くそのような状況になった場合はエラー内容を見て自力で、JSON形式の文字列へ変換する必要が生じます。

以上

<広告>