Pythonでf文字列(f-string)を使う方法
変数の値を文字列に埋め込みたい、計算結果をメッセージに組み込みたい、CSVやログの行を整形したい――プログラミングの現場では、文字列と変数を組み合わせる場面が非常に多くあります。そんなときに大活躍するのが、Python 3.6から導入されたf文字列(フォーマット済み文字列リテラル)です。読みやすさ、書きやすさ、実行速度のすべてにおいて従来の方法を上回る、f文字列の基本から応用、そしてセキュリティ上の注意点まで、プログラミング初心者の方でも確実に使いこなせるように順を追って解説します。
はじめに:f文字列とは
f文字列とは、文字列リテラルの先頭にf(またはF)を付けるだけで、中括弧{}の中に変数や式を直接埋め込める記法です。昔ながらの%書式や.format()メソッドと比べて、「何を埋め込むか」が左から右へ直線的に読めることが最大の特徴です。
# 従来の方法との比較(一目で分かるf文字列の明快さ)
name = "太郎"
age = 25
# ① 旧来の%書式(位置や型指定を覚える必要がある)
message1 = "名前: %s, 年齢: %d" % (name, age)
# ② .format()メソッド(引数と{}の対応を目で追う必要がある)
message2 = "名前: {}, 年齢: {}".format(name, age)
# ③ f文字列(そのまま読める!実行速度も最速)
message3 = f"名前: {name}, 年齢: {age}"
print(message3) # 名前: 太郎, 年齢: 25
Python3つの方法を比較すると、%書式は型指定(%sや%d)を覚える必要があり、.format()は引数の並びと{}の対応を頭で追う必要があります。一方、f文字列は「名前: {name}」と書けば、そのまま表示内容と一致するため、可読性が圧倒的に高いです。実務でも新しいコードではf文字列を標準として使うのが推奨されており、PEP 498(公式仕様)で正式に仕様化されています。
基本編:f文字列の基本的な使い方
基本構文:f”…”と{}で埋め込む
基本はシンプルです。文字列の先頭にfを付け、埋め込みたい場所を{}で囲みます。{}の中には、変数はもちろん、計算式や関数呼び出しもそのまま書けます。
# 基本例:変数と式の埋め込み
name = "花子"
price = 1200
tax_rate = 0.1
# 変数をそのまま埋め込む
print(f"こんにちは、{name}さん")
# 計算式をそのまま書ける(税込み価格の計算)
print(f"税込み価格: {price * (1 + tax_rate)}円") # 税込み価格: 1320.0円
# 関数の戻り値も埋め込める
print(f"文字数: {len(name)}文字") # 文字数: 2文字
# 比較演算や三項演算子も使える
age = 25
print(f"成人: {'Yes' if age >= 20 else 'No'}") # 成人: Yes
Python{}の中に式を書けるのは、f文字列の大きな強みです。「一度変数に代入してから埋め込む」という手順を省略でき、コードがすっきりします。
数値の整形(小数点以下の桁数など)
f文字列では、{}の後ろに:を付けて書式指定を入れることができます。代表的な指定は以下の通りです。
:.2f:小数点以下2桁に丸める(fixed-point):,}:3桁ごとにカンマを入れる(1,000,000):>10}:右寄せで10文字分の幅を確保:<10}:左寄せで10文字分の幅を確保:^10}:中央揃えで10文字分の幅を確保:05d:0埋めで5桁(00042):+.2f:正負の符号を常に表示(+3.14)
# 数値の整形例
price = 1234567.891
print(f"{price:.2f}") # 1234567.89(小数点以下2桁)
print(f"{price:,.2f}") # 1,234,567.89(カンマ区切り+2桁)
print(f"{price:10.2f}") # 1234567.89(10文字分の幅で右寄せ)
print(f"{price:+,.2f}") # +1,234,567.89(符号も表示)
# 0埋め(ファイル名の連番などに便利)
for i in range(3):
print(f"file_{i:03d}.csv") # file_000.csv / file_001.csv / file_002.csv
# パーセント表示
rate = 0.856
print(f"達成率: {rate:.1%}") # 達成率: 85.6%(%書式は自動で×100)
Python書式指定は覚えるのが大変に見えますが、「:の後ろは「.format()の書式指定と同じルール」です。まずは.2f(小数2桁)と,(カンマ区切り)の2つを覚えておけば、実務の大半はカバーできます。
変数の中身をそのまま調べるデバッグ用記法
Python 3.8以降では、{変数名=}と書くと、変数名とその値がセットで出力されるデバッグ用記法が使えます。printデバッグの効率が劇的に上がる便利機能です。
# デバッグ用の = 記法(Python 3.8以降)
x = 10
y = 3
print(f"{x=}") # x=10(変数名と値がセットで出る)
print(f"{x + y=}") # x + y=13(式の内容もそのまま表示)
print(f"{x=}, {y=}, {x*y=}") # x=10, y=3, x*y=30
Python実務編:テンプレートと応用例
実務テンプレート:ログメッセージの整形
実務で頻出する、ログや通知メッセージの整形テンプレートです。書式指定を組み合わせると、見やすく整った出力が簡単に作れます。
# 実務テンプレート:処理結果のレポート文字列を作る
def make_report(username, items_count, total_seconds):
# ユーザー名はそのまま、件数は0埋め、時間は小数1桁で整形
return (
f"【処理完了】ユーザー: {username} / "
f"処理件数: {items_count:03d}件 / "
f"所要時間: {total_seconds:.1f}秒"
)
# 使用例
print(make_report("taro", 42, 3.14159))
# 【処理完了】ユーザー: taro / 処理件数: 042件 / 所要時間: 3.1秒
Python辞書・リストの要素を埋め込む
辞書やリストの要素を埋め込む場合は、{}の中でキーやインデックスを指定します。
# 辞書とリストの要素を埋め込む例
user = {"name": "次郎", "age": 30, "city": "大阪"}
colors = ["赤", "青", "黄"]
# 辞書は[key]、リストは[インデックス]でアクセス
print(f"{user['name']}さん({user['age']}歳)は{user['city']}在住")
# 次郎さん(30歳)は大阪在住
print(f"2番目の色: {colors[1]}") # 2番目の色: 青
# .items()などと組み合わせてループで使う
for key, value in user.items():
print(f" {key}: {value}")
# name: 次郎
# age: 30
# city: 大阪
Pythonオブジェクトの属性を埋め込む
クラスのオブジェクトの属性(フィールド)も、.でアクセスして埋め込めます。
# オブジェクトの属性を埋め込む例
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
product = Product("ノートPC", 98000)
print(f"商品名: {product.name}, 価格: {product.price:,}円")
# 商品名: ノートPC, 価格: 98,000円
Python日時の整形(strftimeとの組み合わせ)
日時オブジェクト(datetime)を扱う場合は、:%Y-%m-%dのような日時フォーマット指定もそのまま使えます。
# 日時の整形例
from datetime import datetime
now = datetime(2026, 10, 9, 18, 30)
print(f"{now:%Y-%m-%d}") # 2026-10-09(日付のみ)
print(f"{now:%Y年%m月%d日}") # 2026年10月09日(日本語フォーマット)
print(f"{now:%H:%M:%S}") # 18:30:00(時刻のみ)
print(f"{now:%Y-%m-%d %H:%M}") # 2026-10-09 18:30(日時)
Python注意すべき重要なポイント
中括弧{}のエスケープ:{{}}とするとリテラルになる
f文字列の中で中括弧そのものを表示したい場合は、{{と}}のように2重に書きます。これはJSON文字列を埋め込みたい場合などによく必要になります。
# 中括弧をリテラルで表示する例
name = "太郎"
# {}を表示したい場合は{{}}と書く
print(f"{{name}}は{name}です") # {name}は太郎です
# JSON風の文字列を作る例
import json
data = {"status": "ok", "user": name}
print(f"レスポンス: {json.dumps(data, ensure_ascii=False)}")
# レスポンス: {"status": "ok", "user": "太郎"}
# ※JSON文字列は直接f文字列に埋め込むだけでOK(中括弧はdumps側が出力する)
Pythonクオートの使い分けに注意
f文字列の中で辞書のキーなどに引用符を使う場合、外側の引用符と同じ引用符を内側に使うとSyntaxErrorになります。
# 【エラー例】外側と内側で同じ引用符を使う
user = {"name": "太郎"}
# f"{user["name"]}さん" # SyntaxError: f-string: unmatched '('
# ↑ 外側が"なのに内側も"だと、どこで文字列が終わるか解釈できない
# 対策1:外側を'にする(推奨)
print(f'{user["name"]}さん') # 太郎さん
# 対策2:内側を'にする
print(f"{user['name']}さん") # 太郎さん
# 対策3:Python 3.12以降なら同じ引用符でもOK(入れ子の解禁)
# print(f"{user["name"]}さん") # 3.12以降は有効
Python「外側はダブルクオート、内側はシングルクオート」と決めておくと、この種のエラーに悩まされません。
変換フラグ:!r、!s、!a
{}の中で!を使うと、値の変換方法を指定できます。!rはrepr()(プログラマ向けの表現)、!sはstr()(人間向けの表現)、!aはascii()(非ASCII文字をエスケープ)を使います。
# 変換フラグの例
text = "こんにちは\n世界"
# !r: repr()相当。改行がエスケープされ、デバッグに適する
print(f"{text!r}") # 'こんにちは\n世界'
# !s: str()相当(デフォルトと同じ)。改行がそのまま表示される
print(f"{text!s}") # こんにちは
# 世界
# !a: ascii()相当。非ASCII文字がエスケープされる
print(f"{text!a}") # '\u3053\u3093\u306b\u3061\u306f\n\u4e16\u754c'
Python特に!rは、「空白や改行が本当に存在するか」を確認したいデバッグ場面で非常に役立ちます。
Noneや未定義変数はエラーになる
f文字列の{}の中は、実際にPythonの式として評価されます。そのため、Noneの属性にアクセスしたり、未定義の変数を参照したりすると、その場でエラー(例外)が発生します。
# f文字列の評価タイミングに注意
name = None
# この時点ではエラーにならない(文字列はまだ作られていない)
template = f"名前: {name}"
# printで実際に評価されるときに初めてNoneが代入される(この例ではOK)
print(template) # 名前: None
# 【エラー例】Noneの属性にアクセスする式を書く
# user = None
# print(f"{user.name}") # AttributeError: 'NoneType' object has no attribute 'name'
# 対策:三項演算子でガードする
user = None
print(f"ユーザー: {user.name if user else '未設定'}") # ユーザー: 未設定
Python外部データを埋め込む場合は、埋め込む前にNoneチェックやデフォルト値の設定を行うか、三項演算子でガードするのが安全です。
セキュリティ上の注意点:SQL埋め込みは絶対NG
f文字列は強力ですが、使い方を誤ると重大な脆弱性を生みます。最も危険なのが、SQL文にf文字列でユーザー入力を直接埋め込むことです。これはSQLインジェクション攻撃の典型的な原因です。
# 【絶対にやってはいけない例】f文字列でSQLを組み立てる
username = input("ユーザー名: ") # 攻撃者が "'; DROP TABLE users; --" と入力する可能性
# f文字列でSQLに直接埋め込む(危険!)
# query = f"SELECT * FROM users WHERE name = '{username}'"
# 攻撃入力でSQL文が書き換えられ、テーブルが削除される可能性がある
# 正しい方法:パラメータ化クエリを使う
import sqlite3
conn = sqlite3.connect(":memory:")
# cursor.execute("SELECT * FROM users WHERE name = ?", (username,))
# ↑ %sや{}ではなく、プレースホルダ(?)を使い、値は必ず引数として渡す
Python原則として、f文字列で作るのは「人間が読む表示用メッセージ」に限定し、機械が解釈する構造化データ(SQL、シェルコマンド、HTMLなど)への埋め込みは絶対に避けてください。構造化データを扱う場合は、それぞれ専用の安全なAPI(パラメータ化クエリ、subprocessのリスト形式、テンプレートエンジンのエスケープなど)を使います。
また、外部からの入力をそのままf文字列でログに埋め込む場合は、ログインジェクション(改行や制御文字でログの改ざん)の可能性も考慮し、!rを使ってエスケープされた形で記録するなどの対策が有効です。
# ログに外部入力を埋め込む際の対策例
user_input = "改行や制御文字\nが含まれる入力"
# !rでエスケープ表示すれば、改行コードが見えて改ざんを防ぎやすい
print(f"[LOG] 受信入力: {user_input!r}")
# [LOG] 受信入力: '改行や制御文字\nが含まれる入力'
Python改ざん防止:機密情報をf文字列で出力しない
f文字列でパスワードやトークンをprintしてしまうと、コンソールログや監視システムに機密情報が残存するリスクがあります。デバッグ用のprintは本番コードから必ず削除し、機密情報の出力は原則として避けるよう、コードレビューでもチェックする項目としておくとよいでしょう。
まとめ
f文字列は、f"..."と書くだけで{}に変数や式を直接埋め込める、現代的で最も推奨される文字列整形方法です。書式指定(:.2fや:,)による数値整形、=によるデバッグ出力、日時フォーマットなど、実務で頻出するテクニックを網羅的に使えます。同じ引用符の入れ子エラーや中括弧のエスケープ({{}})といった文法上の注意点を押さえれば、迷うことはありません。
最も重要なのはセキュリティ上の原則です。f文字列は「人間への表示用」に限定し、SQL・シェルコマンド・HTMLなどへの直接埋め込みは絶対に避けること。これだけを守れば、f文字列は可読性と生産性を大きく向上させる、実務必須のスキルです。まずは手元のスクリプトで、従来の.format()をf文字列に置き換えてみるところから始めてみてください。
