見出し画像

pythonのプログラムの初歩14/templateを自分で実装してみる

こんにちはmakokonです。テンプレートとか使っていますか?
コードやメールの定型文を書くときに重宝しますよね。
有名なテンプレートエンジンとしては、jinja2やMakoとかがあります。LangChainを使うときのtemplatesたちもお馴染みでしょう。
こういった、有名なテンプレートを使いこなすための記事も、需要があるかもしれませんが、今回は、プログラムの初歩なので、このテンプレートを自分で実装して見て、テンプレートがどういうものかを実感しようと言うことです。この記事では、基本的に特別なライブラリは使用しない予定です。



基本的な置換を行うテンプレート

テンプレートの基本的な概念を理解するために、まずはPythonの標準ライブラリだけを使って簡単なテンプレートシステムを構築してみましょう。str.formatメソッドを利用してテンプレートの機能を実現します。

lesson14-00.py

前半がおなじみのf-stringsを使う方法。後半がtemplateを使う方法。str.formatメソッドを利用したテンプレートによる方法ですね。str.formatメソッドはとても強力で応用範囲の広いツールです。今回使ったのは名前付きプレースホルダーというもので、nameの位置に挿入する値をいれる方法です。

print("自己紹介をするプログラムです。")
name = input("名前を入力してください:")

# テンプレートを使わない方法
text=f"私の名前は{name}です。"
print(text)

# テンプレートを使う方法
template="私の名前は{name}です。"
text_with_template = template.format(name=name)
print(text_with_template)

さて、その実行結果は、以下の通り。

>python lesson14-00.py
自己紹介をするプログラムです。
名前を入力してください:makokon
私の名前はmakokonです。
私の名前はmakokonです。

前半も後半も同じ結果ですね。templateをわざわざ定義して、手間が増えただけ?でも、これが基本です。
もうちょっと複雑なことをしてみましょう。

複数の置換を行うプログラム

次のステップは、複数の変数(name、age、place)をテンプレートに埋め込んで表示するプログラムを作成します。

lesson14-01.py

テンプレート文字列には、{name},{age},{place}が含まれています。
これがプレースホルダーです。そのあと、それぞれの変数を定義して、templateに埋め込みます。format()の中で、プレースホルダーと変数が関連付けられて、それぞれ置換されます。

# テンプレート文字列
template = "私の名前は{name}です。年齢は{age}歳で、{place}に住んでいます。"

# 変数
name = "makokon"
age = 30
place = "東京"

# テンプレートに変数を埋め込む
text = template.format(name=name, age=age, place=place)

# 結果を表示
print(text)

結果は以下の通り。間違いなく置換されました。

e>python lesson14-01.py
私の名前はmakokonです。年齢は30歳で、東京に住んでいます。

まだ、テンプレートの効果は、わかりにくいと思うけど、templateの定義と、変数の定義の場所が離れてくると結構効果が想像できるのではないでしょうか。
自己紹介_template= "私の名前は{name}です。年齢は{age}歳で、{place}に住んでいます。"
のような感じで定義してあれば、プログラムのどこでも同じ形式で自己紹介文が作れますよね。

辞書によって置換を行うプログラム

テンプレートの効果がわかりにくいのは、結局変数を定義してまた置換するときにいちいち並べないといけないからかもしれません。そういうときはどうするか。pythonだから辞書が使えると良いですね。

辞書の定義:

person = {"name": "makokon", "age": 30, "place": "東京"}
この辞書には、テンプレートのプレースホルダーに対応する値が含まれています。

lesson14-02.py

# テンプレート文字列
template = "彼の名前は{name}です。年齢は{age}歳で、{place}に住んでいます。"

# 辞書
person = {"name": "makokon", "age": 30, "place": "東京"}

# テンプレートに辞書を使って変数を埋め込む
text = template.format(**person)

# 結果を表示
print(text)

template.format(**person)の書き方が初めてですね。** 演算子は、辞書をアンパックして関数やメソッドに渡すための演算子です。辞書のキーがキーワード引数として渡され、対応する値がその引数の値として使用されます。
つまり、format(**person)はformat(name="makokon", age=30, place="東京")となります。なお、この使い方は関数の引数とかでも利用できるので覚えておくと便利ですよ。

>python lesson14-02.py
彼の名前はmakokonです。年齢は30歳で、東京に住んでいます。

というわけで、結果は当然、正常に置換されました。テンプレートが”彼の・・・”に変わっているのはなぜかですか。それは次の説明の都合ですね。

リストに含まれる複数の辞書を順に置換して表示するプログラム

では早速、この辺になると少し便利さが出てきますね。

リストの定義:

persons = [
{"name": "makokon", "age": 30, "place": "東京"},
{"name": "noln", "age": 25, "place": "大阪"}
]
リストには、2人分の辞書データが入っています。それぞれの辞書の形式は、前と同じですね。

lesson14-03.py

# テンプレート文字列
template = "彼の名前は{name}です。年齢は{age}歳で、{place}に住んでいます。"

# リストに複数の辞書を格納
persons = [
    {"name": "makokon", "age": 30, "place": "東京"},
    {"name": "noln", "age": 25, "place": "大阪"}
]

# リスト内の各辞書を順にテンプレートに埋め込んで表示
for person in persons:
    text = template.format(**person)
    print(text)

for person in persons: で辞書を順番に取り出して、templateに挿入します。pythonの定番処理ですね。

>python lesson14-03.py
彼の名前はmakokonです。年齢は30歳で、東京に住んでいます。
彼の名前はnolnです。年齢は25歳で、大阪に住んでいます。

ここまで来ると、テンプレートによる処理がコードの見通しを非常に良くしていることがわかります。
参考までに、f-stringsを使って同じ内容を表示する例を示します。

外部ファイルから設定を読み込むプログラム


テンプレート文字列と複数の人物情報を含む person_config.json ファイルを読み込み、テンプレートを用いてデータを表示する方法を学びました。JSONファイルを使うことで、データの管理が容易になり、プログラムの柔軟性も向上します。この方法を使うと、外部ファイルから動的にデータを読み込んで処理することができ、より実用的なプログラムを作成することができます。

{
    "template": "彼の名前は{name}です。年齢は{age}歳で、{place}に住んでいます。",
    "persons": [
        {"name": "makokon", "age": 30, "place": "東京"},
        {"name": "noln", "age": 25, "place": "大阪"}
    ]
}
import json

# JSONファイルを読み込む
with open('person_config.json', 'r', encoding='utf-8') as file:
    data = json.load(file)

# テンプレート文字列と人物情報を取得
template = data["template"]
persons = data["persons"]

# リスト内の各辞書を順にテンプレートに埋め込んで表示
for person in persons:
    text = template.format(**person)
    print(text)
    
>python lesson14-05.py
彼の名前はmakokonです。年齢は30歳で、東京に住んでいます。
彼の名前はnolnです。年齢は25歳で、大阪に住んでいます。

まとめ

テンプレートを利用することで得られる便利さは以下の通りです:

  • 可読性の向上: テンプレートを使うことで、どの部分が動的に変わるのかが明確になります。

  • 再利用性の向上: テンプレートを使い回すことで、同じフォーマットの異なるデータを簡単に表示できます。

  • データ管理の一元化: 辞書やJSONファイルを使うことで、データを一つの場所で管理でき、コードが整理されます。

  • 柔軟性とスケーラビリティの向上: リストやJSONファイルを使うことで、複数のデータを効率的に処理でき、データの追加や変更にも柔軟に対応できます。

振り返り


以下にこの記事を振り返ってみます。(蛇足)

1. 基本的なテンプレートの利用

最初に、テンプレート文字列を使って変数を埋め込む方法を学びました。これにより、固定の文言と動的なデータを分離し、簡単にデータを置換できるようになりました。
便利さ:

  • 可読性の向上: テンプレート文字列を使うことで、構造が明確になり、どの部分が動的に変わるのかが一目でわかります。

  • 再利用性: 同じテンプレートを使って、異なるデータを埋め込むことができるため、コードの再利用性が高まります。

2. 辞書を使ったテンプレートの置換

次に、辞書を使ってテンプレートのプレースホルダーを置換する方法を学びました。これにより、複数の変数を一つのデータ構造にまとめることができ、コードがより整理されました。
便利さ:

  • データ管理の一元化: 辞書を使うことで、複数の変数を一つのデータ構造にまとめて管理できます。

  • 柔軟性の向上: 辞書を使うことで、テンプレートのプレースホルダーと対応するデータを簡単に変更できます。

3. 複数のデータを順に処理

リストに複数の辞書を格納し、それを順にテンプレートに置換して表示するプログラムを作成しました。これにより、複数のデータを効率的に処理できるようになりました。

便利さ:

  • 一括処理: リストを使うことで、複数のデータを一括で処理できます。

  • スケーラビリティ: データの数が増えても、同じコードで対応できるため、プログラムのスケーラビリティが向上します。

4. JSONファイルからのデータ読み込み

最後に、テンプレートとデータを含むJSONファイルを読み込み、テンプレートを用いてデータを表示する方法を学びました。これにより、データの外部管理が可能になり、プログラムの柔軟性が大幅に向上しました。

便利さ:

  • データの外部管理: JSONファイルを使うことで、プログラムコードからデータを分離し、データ管理が容易になります。

  • 動的なデータ更新: JSONファイルを編集するだけで、プログラムを再実行することなくデータを更新できます。


付録 str.formatメソッドの使い方

今回の記事で大活躍したstr.formatメソッドの主要な使い方です。今回紹介しなかった使い方も含まれていますが、使いこなせれば強力なツールになるでしょう。

  • 基本的な使い方: {} プレースホルダーを使って値を挿入。
    プレースホルダーは波括弧 {} で囲まれた部分に指定します。str.format メソッドの引数として渡された値が、プレースホルダーの位置に挿入されます。

template = "私の名前は{}です"
name = "name1"
text = template.format(name)
print(text)  # 出力: 私の名前はname1です
  • 名前付きプレースホルダー: {name} のように名前を付けて挿入。
    プレースホルダーに名前を付けることで、挿入する値を特定できます。

template = "私の名前は{name}です"
text = template.format(name="name1")
print(text)  # 出力: 私の名前はname1です
  • 複数のプレースホルダー: 複数の値を挿入可能。
    複数のプレースホルダーを使って複数の値を挿入することができます。名前付きプレースホルダーを使うと、順序を気にせずに値を挿入できます。

template = "私の名前は{name}で、年齢は{age}歳です"
text = template.format(name="name1", age=30)
print(text)  # 出力: 私の名前はname1で、年齢は30歳です
  • フォーマットオプション: 数値のフォーマットや文字列の配置を制御可能。
    str.format メソッドは、プレースホルダーの中でフォーマットオプションを使って、数値のフォーマットや文字列の配置を制御することができます。

数値のフォーマット

template = "小数点以下2桁: {:.2f}"
value = 3.14159
text = template.format(value)
print(text)  # 出力: 小数点以下2桁: 3.14

文字列の配置

template = "|{:^10}|"
text = template.format("center")
print(text)  # 出力: |  center  | (中央寄せで10文字幅)
  • インデックスを使ったプレースホルダー: 引数の位置を指定可能。
    引数の位置を指定することもできます。

template = "名前: {0}, 年齢: {1}"
text = template.format("name1", 30)
print(text)  # 出力: 名前: name1, 年齢: 30
  • 辞書を使ったフォーマット: 辞書を使って値を渡すことも可能。
    辞書を使って、値を渡すこともできます。

template = "名前: {name}, 年齢: {age}"
data = {"name": "name1", "age": 30}
text = template.format(**data)
print(text)  # 出力: 名前: name1, 年齢: 30

これらの機能を組み合わせることで、非常に柔軟かつ強力な文字列フォーマットが可能になります。

#PythonProgramming #CodingForBeginners #TemplateEngine #PythonTutorial #ProgrammingTips
#Pythonプログラミング #初心者向けコーディング #テンプレートエンジン #Pythonチュートリアル #プログラミングのコツ


この記事が気に入ったらサポートをしてみませんか?