0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】dataclassで初心者が必ずハマる default_factory の罠を徹底解説

Posted at

Python の dataclass を使い始めてしばらくすると、必ず遭遇するバグがあります。
そして原因はだいたい mutable(可変)なデフォルト値

今日はこの罠を避けるための default_factory を、かみ砕いて解説します。


✅ 結論

list / dict / set などの可変オブジェクトをデフォルト値にしたい場合、必ず default_factory を使うべき!


🔥 初心者が必ずやる「危険な例」

from dataclasses import dataclass

@dataclass
class User:
    tags: list = []

一見良さそうに見えますが…

u1 = User()
u2 = User()

u1.tags.append("python")

print(u1.tags)  # ['python']
print(u2.tags)  # ['python'] ←!??

なぜか u2 にも値が反映されてしまいます。


❓なぜこうなるの?

理由は Python の仕様。

  • デフォルト引数(=tags=[])は
  • 定義時に一度だけ評価される

つまり、この []
全インスタンスで共有されるリストになってしまうのです。

Python界隈では「可変デフォルト引数の罠」と呼ばれる有名な事故ポイント。


✅ 正しい書き方:default_factory=list

from dataclasses import dataclass, field

@dataclass
class User:
    tags: list = field(default_factory=list)

動作を確認:

u1 = User()
u2 = User()

u1.tags.append("python")

print(u1.tags)  # ['python']
print(u2.tags)  # []

今度は独立しました 🎉


🧠 default_factory の仕組み

default_factory=list は内部的には

tags = list()

として インスタンスごとに新しいリストを生成します。


✅ どんなときに default_factory を使う?

default OK? コメント
list 共有バグの原因
dict 共有されるので危険
set 同上

逆に不可変な型は OK:

default OK? コメント
int 変更不能
float 同上
str 同上
tuple 同上

✅ 実務でよく見るパターン

部下IDを管理するエージェントモデル:

@dataclass
class Agent:
    subordinate_ids: list = field(default_factory=list)

あるあるですね。


🧩 defaultdefault_factory の違いまとめ

default default_factory
評価タイミング 定義時に一回 インスタンス生成ごと
可変オブジェクト ❌危険 ✅安全
不可変オブジェクト ✅OK ✅OK

✅ 関数(callable)なら何でも渡せる

field(default_factory=dict)
field(default_factory=set)
field(default_factory=lambda: [1, 2, 3])

例:タイムスタンプ自動生成

from datetime import datetime

@dataclass
class Log:
    timestamp: datetime = field(default_factory=datetime.now)

❌(補足)「それでも default で良いよね?」は危険

共有バグは

  • 発生頻度低い
  • 再現性が低い
  • 見落としやすい

そして本番事故になりやすい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?