Pythonで自動生成スクリプトを作りたいけどめんどくさい
という人向けに「自動生成スクリプトを手軽に使えるスクリプト」を紹介します
使い方
必要環境
・Python3
・Jinja2
必要ファイル
・実行ファイル:auto_generate.py
・テンプレート:template.j2
・テキストファイル(1つ以上):data1.txt
・実行コマンド
./auto_generate.py template.j2 data1.txt
使用例
下記のようなエクセルファイルがあるとします。
これをdata1.txtというテキストファイルにコピペします。
また、下記のようなテンプレート(template.j2)があるとします。
そしてコマンドを実行します
./auto_generate.py template.j2 data1.txt
そうするとこんな結果が得られます。
コード
auto_generate.py
import os
import sys
import jinja2
def check_error(file_pathes):
"""エラーチェックをする"""
for file_path in file_pathes:
if not os.path.exists(file_path):
sys.exit("{} is not found".format(file_path))
if len(file_pathes) <= 2:
sys.exit("There are not enough arguments")
def create_data(args):
"""テンプレートで使う文字列を作成する"""
filenames = [os.path.splitext(os.path.basename(arg))[0] for arg in args]
data = {"{}".format(os.path.splitext(filename)[0]):[] for filename in filenames}
for arg in args:
with open(arg, "r") as f:
data[os.path.splitext(os.path.basename(arg))[0]] = [i.replace("\n", "").split() for i in f]
return data
def execute_jinja2(j2_path, data):
"""Jinjaのテンプレートを読み込む"""
j2_dir_path = os.path.dirname(j2_path)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(j2_dir_path),
trim_blocks=True,
lstrip_blocks=True,
)
template = env.get_template(os.path.basename(j2_path))
return template.render(data=data)
if __name__ == "__main__":
check_error(sys.argv)
result = execute_jinja2(sys.argv[1], create_data(sys.argv[2:]))
print(result)
コードの解説
def check_error(file_pathes):
"""エラーチェックをする"""
for file_path in file_pathes:
if not os.path.exists(file_path):
sys.exit("{} is not found".format(file_path))
if len(file_pathes) <= 2:
sys.exit("There are not enough arguments")
file_pathesで与えたファイルが存在するかチェックします。
ない場合はエラーで終了します。
また、引数が2以下(Jinjaファイルとテキストファイル)でもエラーを出します。
def create_data(args):
"""テンプレートで使う文字列を作成する"""
filenames = [os.path.splitext(os.path.basename(arg))[0] for arg in args]
data = {"{}".format(os.path.splitext(filename)[0]):[] for filename in filenames}
for arg in args:
with open(arg, "r") as f:
data[os.path.splitext(os.path.basename(arg))[0]] = [i.replace("\n", "").split() for i in f]
return data
Jinjaファイルで使うデータを成型します。
成型といっても、引数にしたテキストファイルをキーにした辞書を作成します。
Jinjaファイル内で使う場合はdata[<ファイル名>]のように使えます。
def execute_jinja2(j2_path, data):
"""Jinjaのテンプレートを読み込む"""
j2_dir_path = os.path.dirname(j2_path)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(j2_dir_path),
trim_blocks=True,
lstrip_blocks=True,
)
template = env.get_template(os.path.basename(j2_path))
return template.render(data=data)
Jinjaを使う準備をしています。Jinjaの詳しい使い方はここでは割愛しますが、
上記の関数にJinjaファイルのパスとデータを与えることでテンプレートを作成できます。
if __name__ == "__main__":
check_error(sys.argv)
result = execute_jinja2(sys.argv[1], create_data(sys.argv[2:]))
print(result)
check_error(sys.argv)
実行時に与えた引数が存在するかチェックします。
ない場合はエラーを出して終了します。
result = execute_jinja2(sys.argv[1], create_data(sys.argv[2:]))
sys.argv[0]は実行ファイル自身(ここではauto_generate.py)なので
sys.argv[1]でexecute_jinja2にJinjaファイルを与えています。
create_data(sys.argv[2:])では、Jinjaファイルで使うデータ(data1.txtから取得したデータ)を生成します。
結果をexecute_jinja2に与えます。
まとめ
Jinjaを使った自動生成を手軽にできるスクリプトを作成しました。
ぜひ使ってみて下さい。
コメント