はじめに: テンプレート文字列(t-string)とは?
Python3.14で、テンプレート文字列(t-string)が新たに導入されました。
t-stringはf-stringに似た構文で、リテラルとして文字列テンプレートを定義することができます。
name = '太郎'
f'名前: {name}' # '名前: 太郎'
name = '太郎'
t'名前: {name}' # Template(strings=('名前: ', ''), interpolations=(Interpolation('太郎', 'name', None, ''),))
f-stringとの違いは、{} に挿入した値を構造として保持している点です。
f-stringは定義した時点でstr型のリテラルになります。埋め込んだオブジェクト("太郎")を後から変えることはできません。
一方、t-stringは{}の中に埋め込んだオブジェクトを保持しています。
>>> t_str = t'名前: {name}'
>>> parts = list(t_str)
>>> parts[0] # {}の手前まで
'名前: '
>>> parts[1] # {}の中身
Interpolation('太郎', 'name', None, '')
そのため、中身を取り出して変換してから文字列を生成することも可能です。
実際、上記のPEP 750の説明にもHTMLの属性に変換する例が紹介されています。
# 属性を辞書で定義
attributes = {'src': 'limburger.jpg', 'alt': 'lovely cheese'}
template = t'<img {attributes}>'
# 関数 html でエスケープ
# attributesは文字列 'src="limburger.jpg" alt="lovely cheese"' に変換されている
assert html(template) == '<img src="limburger.jpg" alt="lovely cheese" />'
また、SQLのサニタイザー等セキュリティ用途での利用も期待できます。
便利ですね!
...でも私は、もっとt-stringの可能性を知りたい。
圧倒的なテンプレートを見せつけたい!
作ったもの
強大なるt-string、その《構造(ストラクチャ)》を汝に託す。
厨 二 タ イ ザ ー
- t-stringに伝承を刻む
from chunitizer import chunitize
man = 'おじいさん'
woman = 'おばあさん'
houseworks = [
{'place': '山', 'task': '芝刈り'},
{'place': '川', 'task': '洗濯'},
]
t_str = t'''
むかしむかしあるところに、{man}と{woman}が暮らしていました。
{man}は{houseworks[0]['place']}へ{houseworks[0]['task']}に、{woman}は{houseworks[1]['place']}へ{houseworks[1]['task']}に行きました。
'''
- 関数によりinterpolationの言霊を覚醒
print(chunitize(t_str))
- 文章が秘めたる「力」を解き放つ
むかしむかしあるところに、永劫の賢者と悠久の賢者が暮らしていました。
永劫の賢者は天衝へ翠統の儀に、悠久の賢者は龍脈へ聖衣再生に行きました。
仕組み
t-stringを受け取る関数
疲れたので普通の口調に戻します
テンプレートを加工する関数の中身はこのようになっています。
from string.templatelib import Interpolation, Template
def chunitize(template: Template):
parts = []
for part in template:
if isinstance(part, Interpolation):
parts.append(to_chuni(str(part.value)))
else:
parts.append(part)
return ''.join(parts)
template は、t-stringの構成要素のイテレータとなっています。{} で埋め込まれた値およびその前後の文字列が先頭から順番に格納されています。
| index | 内容 |
|---|---|
| [0] | "むかしむかしあるところに、" |
| [1] | Interpolation ("おじいさん") |
| [2] | "と" |
| [3] | Interpolation ("おばあさん") |
| ... | ... |
今回は埋め込まれた内容だけを変換したいため、 Interpolation のインスタンスであった場合のみ変換を行っています。
得られた結果(または変換していないそのままの要素)はlistに格納し、最後に結合して1つの文字列にします。
上記の設計は、変換の内容によらずある程度使いまわせると思います1。
埋め込まれた値の厨二化
(※この節は本題のt-stringとは関係ありません)
続いて、埋め込まれたそれぞれの値(文字列)を変換します。
困った時のLLM。
SDK組み込みやAPIトークン発行が面倒だったので Gemini CLIを呼び出しています。
import subprocess
prompt = '''
以下の単語を厨二病っぽく言い換えてください。
なるべくスケールの大きいカッコ良い言葉が理想です。
ただし、回答として該当する単語だけを答えてください。
---
'''
def to_chuni(value: str):
# -p オプションを使いプロンプトを渡す。非対話モードになるのでstdoutで回答が得られる
result = subprocess.run(
['gemini', '-p', prompt + value, '-m', 'gemini-2.5-flash'],
capture_output=True, text=True)
# 改行が邪魔なので削除
return result.stdout.replace('\n', '')
この関数によって以下のコマンドが実行され、厨二化された文字列が得られます。
$ gemini -p "以下の単語を厨二病っぽく...\n---\nおじいさん" -m "gemini-2.5-flash-lite"
永劫の賢者
上記の実装だと、埋め込まれた文字列に同じものがあった場合毎回リクエストされるので非効率ですね...
改良方法の検討は読者への課題とします
おわりに
以上、t-stringを使っ て《錦蛇》の秘めたる力を解放し た紹介でした。
みなさんも文字列に埋め込んだ値を加工したい際にt-stringを使ってみてはいかがでしょうか?