事の発端
以前作成したPython形式のファイルをJSON形式のファイルに書き換えたいと思い立ち,
- 変換対象のファイルから変数(中身は数字,文字,リスト,None,ブーリアン等)をインポート
- インポートした変数を辞書型に変更
- JSON形式で保存
を行う変換コードをPythonで作成してみました.変換対象のPythonファイルが1つであれば,変換コードの文頭で静的にインポートして万事解決でしたが,当該のPythonファイルが複数存在していたため,変換コード内でfor文を使用して一つ一つ変換していく運びになりました.
ところが,文頭以外で別のPythonファイルをインポートする方法を知らなかったため,「importlib」というパッケージを使用して文中で動的にインポートするということにしました.
変換対象のファイルの例
このようなファイルが複数個存在しています.また,格納先は
/hoge/src/
内となっています.
/hoge/src/example.py
# 日付と番号
date = ["20230607", 3]
# 名前
name = "佐藤太郎"
# 項目_1
item_1 = 200
# 項目_2
item_2 = [["松", 1], ["竹", 2], ["梅", 3]]
# 項目_3
item_3 = False
# 項目_4(場合によっては二重リストの可能性あり)
item_4 = None
item_4 = [["序", 4], ["破", 5], ["急", 6]]
作成中の変換のコード(Python形式)の例
こちらのコードは
/hoge/
内に格納されています.for文を使用して対象ファイル一つ一つに対して動的なインポート作業とJSON形式への出力作業を行うようにしています.
/hoge/main.py
import os
import json
from importlib import import_module
# インポートするPythonファイルを格納しているディレクトリ
dir_src = "/hoge/src/"
# 保存先のディレクトリ
dir_out = "/hoge/json/"
# インポートするPythonファイル名を与えると,当該ファイル内の変数をインポートし,必要に応じて変数を処理するクラス
class FileReader:
def __init__(self, name_src: str) -> None:
"""
Import variables in the input python file
Args:
name_src (str): name of the source python file
"""
# 拡張子を除去したPythonファイルの名前
name_base = os.path.splitext(name_src)[0]
# Pythonファイルのインポート
python_file = import_module("src." + name_base)
# 日付と番号
self.date = python_file.date
# 名前
self.name = python_file.name
# 項目_1
self.number = python_file.item_1
# 項目_2
self.list = {
"item_2-1": {
"sort": python_file.item_2[0][0],
"number": python_file.item_2[0][1],
},
"item_2-2": {
"sort": python_file.item_2[1][0],
"number": python_file.item_2[1][1],
},
"item_2-3": {
"sort": python_file.item_2[2][0],
"number": python_file.item_2[2][1],
},
}
# 項目_3
self.boolean = python_file.item_3
# 項目_4
if python_file.item_4 == None:
# Noneであれば変更なし
self.none = python_file.item_4
else:
# 二重リストであれば辞書型に変更
self.none = {}
for i in range(0, len(python_file.item_4)):
self.none[python_file.item_4[i][0]] = python_file.item_4[i][1]
for file in os.listdir(dir_src):
inp = FileReader(name_src=file)
# インポートしたデータを辞書型へ変更
out = {
"general": {"date": inp.date[0], "trial": inp.date[1], "name": inp.name},
"items": {
"item_1": inp.number,
"item_2": inp.list,
"item_3": inp.boolean,
"item_4": inp.none,
},
}
# JSON形式で出力
json_name = inp.date[0] + "_" + str(inp.date[1]).zfill(2) + ".json"
json_file = os.path.join(dir_out, json_name)
with open(json_file, "w") as f:
json.dump(out, f, indent=2, ensure_ascii=False)
結果
上手く変換できました.
/hoge/json/20230607_03.json
{
"general": {
"date": "20230607",
"trial": 3,
"name": "佐藤太郎"
},
"items": {
"item_1": 200,
"item_2": {
"item_2-1": {
"sort": "松",
"number": 1
},
"item_2-2": {
"sort": "竹",
"number": 2
},
"item_2-3": {
"sort": "梅",
"number": 3
}
},
"item_3": false,
"item_4": {
"序": 4,
"破": 5,
"急": 6
}
}
}