Python f-string(テンプレートリテラル)完全ガイド – 文字列フォーマットの最新手法
Python 3.6で導入されたf-string(Formatted String Literals)は、文字列フォーマットの革命的な機能です。JavaScriptのテンプレートリテラルに類似した記法で、従来の%
フォーマットやformat()
メソッドよりも高速で読みやすい文字列作成が可能です。この記事では、f-stringの基本から高度な使用法まで、実践的なサンプルコードとともに詳しく解説します。
f-string(テンプレートリテラル)とは
f-stringは、Python 3.6で導入された文字列リテラルの記法で、文字列の前にf
またはF
を付けることで、波括弧{}
内にPython式を直接埋め込むことができます。実行時に式が評価され、結果が文字列に埋め込まれます。
基本構文
name = "Python"
message = f"Hello, {name}!"
print(message) # Hello, Python!
基本的な使い方
1. 変数の埋め込み
language = "Python"
version = 3.9
message = f"{language}のバージョンは{version}です"
print(message) # Pythonのバージョンは3.9です
2. 式の直接評価
x = 10
y = 20
result = f"{x} + {y} = {x + y}"
print(result) # 10 + 20 = 30
3. 関数呼び出し
import datetime
now = f"現在時刻: {datetime.datetime.now()}"
print(now) # 現在時刻: 2025-07-29 14:30:45.123456
4. メソッドチェーン
text = "python programming"
formatted = f"大文字: {text.title()}"
print(formatted) # 大文字: Python Programming
数値フォーマット
小数点以下の桁数指定
pi = 3.14159265359
formatted = f"円周率: {pi:.3f}"
print(formatted) # 円周率: 3.142
整数の0埋め
number = 42
formatted = f"ID: {number:05d}"
print(formatted) # ID: 00042
三桁区切り
amount = 1234567
formatted = f"金額: {amount:,}円"
print(formatted) # 金額: 1,234,567円
パーセント表示
ratio = 0.8567
formatted = f"成功率: {ratio:.1%}"
print(formatted) # 成功率: 85.7%
科学的記数法
large_number = 123456789
formatted = f"大きな数: {large_number:.2e}"
print(formatted) # 大きな数: 1.23e+08
文字列の配置とパディング
左寄せ・右寄せ・中央寄せ
text = "Python"
print(f"左寄せ: '{text:<10}'") # 左寄せ: 'Python '
print(f"右寄せ: '{text:>10}'") # 右寄せ: ' Python'
print(f"中央寄せ: '{text:^10}'") # 中央寄せ: ' Python '
埋め文字の指定
text = "Hello"
print(f"星埋め: '{text:*<10}'") # 星埋め: 'Hello*****'
print(f"等号埋め: '{text:=^10}'") # 等号埋め: '==Hello==='
数値の符号表示
positive = 42
negative = -15
print(f"正数: {positive:+d}") # 正数: +42
print(f"負数: {negative:+d}") # 負数: -15
print(f"空白パディング: {positive: d}") # 空白パディング: 42
進数変換
2進数・8進数・16進数
number = 255
print(f"2進数: {number:b}") # 2進数: 11111111
print(f"8進数: {number:o}") # 8進数: 377
print(f"16進数: {number:x}") # 16進数: ff
print(f"16進数(大文字): {number:X}") # 16進数(大文字): FF
プレフィックス付き表示
number = 255
print(f"2進数: {number:#b}") # 2進数: 0b11111111
print(f"8進数: {number:#o}") # 8進数: 0o377
print(f"16進数: {number:#x}") # 16進数: 0xff
日付と時刻のフォーマット
datetime オブジェクト
from datetime import datetime
now = datetime.now()
formatted = f"日時: {now:%Y年%m月%d日 %H:%M:%S}"
print(formatted) # 日時: 2025年07月29日 14:30:45
ISO形式とカスタム形式
from datetime import datetime
now = datetime.now()
print(f"ISO形式: {now:%Y-%m-%d}") # ISO形式: 2025-07-29
print(f"和暦風: {now:%Y年%m月%d日(%a)}") # 和暦風: 2025年07月29日(Tue)
辞書とオブジェクトのアクセス
辞書の値アクセス
person = {"name": "田中", "age": 30, "city": "東京"}
message = f"{person['name']}さんは{person['age']}歳で{person['city']}在住です"
print(message) # 田中さんは30歳で東京在住です
オブジェクトの属性アクセス
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person("佐藤", 25)
message = f"{person.name}さんは{person.age}歳です"
print(message) # 佐藤さんは25歳です
リストの要素アクセス
fruits = ["りんご", "バナナ", "オレンジ"]
message = f"好きな果物: {fruits[0]}, {fruits[1]}, {fruits[2]}"
print(message) # 好きな果物: りんご, バナナ, オレンジ
高度な式の評価
三項演算子
score = 85
result = f"結果: {'合格' if score >= 60 else '不合格'}"
print(result) # 結果: 合格
リスト内包表記
numbers = [1, 2, 3, 4, 5]
squared = f"平方数: {[x**2 for x in numbers]}"
print(squared) # 平方数: [1, 4, 9, 16, 25]
関数の定義と呼び出し
def square(x):
return x ** 2
n = 5
result = f"{n}の平方は{square(n)}です"
print(result) # 5の平方は25です
lambda式の使用
numbers = [1, 2, 3, 4, 5]
result = f"偶数: {list(filter(lambda x: x % 2 == 0, numbers))}"
print(result) # 偶数: [2, 4]
動的なフォーマット指定
変数による幅指定
width = 15
text = "Python"
formatted = f"'{text:^{width}}'"
print(formatted) # ' Python '
変数による精度指定
precision = 4
pi = 3.14159265359
formatted = f"円周率: {pi:.{precision}f}"
print(formatted) # 円周率: 3.1416
動的な埋め文字
fill_char = '*'
width = 10
text = "Hello"
formatted = f"'{text:{fill_char}^{width}}'"
print(formatted) # '**Hello***'
実践的な使用例
1. データテーブルの生成
products = [
("Python入門", 2800, 4.5),
("Web開発", 3200, 4.2),
("機械学習", 4500, 4.8)
]
print(f"{'商品名':<12} | {'価格':>6} | {'評価':>4}")
print("-" * 28)
for name, price, rating in products:
print(f"{name:<12} | {price:>6,} | {rating:>4.1f}")
2. ログメッセージの生成
import logging
from datetime import datetime
def create_log_message(level, message, user_id=None):
timestamp = datetime.now()
user_info = f" [User:{user_id}]" if user_id else ""
return f"[{timestamp:%Y-%m-%d %H:%M:%S}] {level:<5}: {message}{user_info}"
log_msg = create_log_message("ERROR", "データベース接続失敗", "user123")
print(log_msg) # [2025-07-29 14:30:45] ERROR: データベース接続失敗 [User:user123]
3. API レスポンスの生成
def generate_api_response(status, data, message=None):
response_time = datetime.now()
msg_part = f', "message": "{message}"' if message else ''
return f'{{"status": "{status}", "data": {data}, "timestamp": "{response_time:%Y-%m-%dT%H:%M:%S}"{msg_part}}}'
response = generate_api_response("success", '{"count": 5}', "データを正常に取得しました")
print(response)
4. 設定ファイルの動的生成
config = {
"server_host": "localhost",
"server_port": 8080,
"debug_mode": True,
"max_connections": 100,
"timeout": 30.5
}
config_text = f"""
# サーバー設定ファイル
SERVER_HOST = "{config['server_host']}"
SERVER_PORT = {config['server_port']}
DEBUG = {str(config['debug_mode']).lower()}
MAX_CONNECTIONS = {config['max_connections']:d}
TIMEOUT = {config['timeout']:.1f}
""".strip()
print(config_text)
パフォーマンス比較
従来手法との速度比較
import timeit
name = "Python"
version = 3.9
# %フォーマット
time1 = timeit.timeit(lambda: "%s version %s" % (name, version), number=100000)
# format()メソッド
time2 = timeit.timeit(lambda: "{} version {}".format(name, version), number=100000)
# f-string
time3 = timeit.timeit(lambda: f"{name} version {version}", number=100000)
print(f"% フォーマット: {time1:.4f}秒")
print(f"format()メソッド: {time2:.4f}秒")
print(f"f-string: {time3:.4f}秒")
デバッグとトラブルシューティング
デバッグ用の便利な記法
x = 10
y = 20
# Python 3.8以降: = を使った変数名の表示
print(f"{x=}, {y=}, {x+y=}") # x=10, y=20, x+y=30
複雑な式のデバッグ
def complex_calculation(a, b, c):
result = (a + b) * c / 2
print(f"{a=}, {b=}, {c=} → 結果: {result}")
return result
value = complex_calculation(5, 10, 3) # a=5, b=10, c=3 → 結果: 22.5
エラーハンドリング
def safe_format(template_func):
"""f-stringを安全に実行する装飾子"""
try:
return template_func()
except (NameError, AttributeError, KeyError) as e:
return f"フォーマットエラー: {e}"
# 使用例
undefined_var = None
result = safe_format(lambda: f"値: {undefined_var.value}")
print(result) # フォーマットエラー: 'NoneType' object has no attribute 'value'
特殊文字とエスケープ
波括弧のエスケープ
name = "Python"
# 波括弧を文字として表示したい場合
message = f"{{言語: {name}}}"
print(message) # {言語: Python}
引用符の扱い
title = "Python入門"
# 引用符を含む文字列
message = f'書籍「{title}」を読了しました'
print(message) # 書籍「Python入門」を読了しました
改行を含む長い文字列
name = "田中"
age = 30
city = "東京"
# 複数行のf-string
profile = f"""
プロフィール:
名前: {name}
年齢: {age}歳
居住地: {city}
""".strip()
print(profile)
国際化とローカライゼーション
多言語対応
def localized_greeting(name, lang="ja"):
greetings = {
"ja": f"こんにちは、{name}さん!",
"en": f"Hello, {name}!",
"es": f"¡Hola, {name}!",
"fr": f"Bonjour, {name}!"
}
return greetings.get(lang, greetings["en"])
print(localized_greeting("田中", "ja")) # こんにちは、田中さん!
print(localized_greeting("Smith", "en")) # Hello, Smith!
数値の地域化
import locale
def format_currency(amount, currency="JPY"):
if currency == "JPY":
return f"¥{amount:,.0f}"
elif currency == "USD":
return f"${amount:,.2f}"
elif currency == "EUR":
return f"€{amount:,.2f}"
amount = 1234567.89
print(format_currency(amount, "JPY")) # ¥1,234,568
print(format_currency(amount, "USD")) # $1,234,567.89
ベストプラクティス
1. 読みやすさを重視
# 良い例: 明確で読みやすい
user_name = "田中太郎"
login_count = 42
last_login = datetime.now()
message = f"""
ユーザー情報:
名前: {user_name}
ログイン回数: {login_count:,}回
最終ログイン: {last_login:%Y-%m-%d %H:%M}
""".strip()
2. 複雑な式は事前に計算
# 良い例: 複雑な計算は変数に分ける
data = [10, 20, 30, 40, 50]
average = sum(data) / len(data)
max_value = max(data)
min_value = min(data)
summary = f"平均: {average:.1f}, 最大: {max_value}, 最小: {min_value}"
print(summary) # 平均: 30.0, 最大: 50, 最小: 10
3. 長い文字列の分割
# 良い例: 長い文字列は適切に分割
def create_email_body(name, product, price, shipping_date):
return (
f"「{name}」様\n\n"
f"ご注文いただいた「{product}」({price:,}円)の\n"
f"発送予定日は{shipping_date:%m月%d日}です。\n\n"
f"お問い合わせは support@example.com まで。"
)
email = create_email_body("田中", "Python入門書", 2800, datetime(2025, 8, 1))
print(email)
セキュリティの考慮事項
危険な評価の回避
# 危険: ユーザー入力を直接評価
# user_input = "os.system('rm -rf /')" # 絶対にやってはいけない
# result = f"結果: {eval(user_input)}"
# 安全: 事前に検証された値のみ使用
def safe_user_message(username, message):
# 入力の検証とサニタイズ
clean_username = str(username).replace('{', '').replace('}', '')
clean_message = str(message).replace('{', '').replace('}', '')
return f"[{clean_username}]: {clean_message}"
result = safe_user_message("user123", "Hello World!")
print(result) # [user123]: Hello World!
将来の拡張機能
Python 3.8以降の新機能
# = を使った変数名の表示(Python 3.8+)
x = 42
y = 24
print(f"{x=}, {y=}") # x=42, y=24
# 計算結果も表示
print(f"{x + y = }") # x + y = 66
カスタムフォーマッターの実装
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
def __format__(self, format_spec):
if format_spec == 'f':
fahrenheit = self.celsius * 9/5 + 32
return f"{fahrenheit:.1f}°F"
elif format_spec == 'k':
kelvin = self.celsius + 273.15
return f"{kelvin:.1f}K"
return f"{self.celsius:.1f}°C"
temp = Temperature(25)
print(f"温度: {temp}, {temp:f}, {temp:k}") # 温度: 25.0°C, 77.0°F, 298.1K
まとめ
f-string(テンプレートリテラル)は、Pythonの文字列フォーマットにおける最も現代的で効率的な手法です。従来の%
フォーマットやformat()
メソッドと比較して、読みやすく、高速で、より柔軟な表現が可能です。
主なポイント:
- 高い可読性: 変数や式を直接埋め込める直感的な記法
- 優れたパフォーマンス: 他のフォーマット手法より高速
- 豊富な機能: 数値フォーマット、日付処理、配置、進数変換
- 強力な式評価: 関数呼び出し、三項演算子、リスト内包表記
- デバッグ支援: Python 3.8以降の
=
記法 - 安全性: 適切な入力検証とエスケープの実装
Python 3.6以降を使用している場合は、f-stringを積極的に活用することで、より保守性が高く効率的なコードを書くことができます。
参考リンク
- PEP 498 – Literal String Interpolation
- Python公式ドキュメント – f-string
- Python公式ドキュメント – Format Specification
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座