エラーの内容
深夜2時にスクリプトがこのエラーで落ちた場合:
TypeError: 'str' object is not callable
トレースバックは一見問題なさそうな行を指しています。本当の原因はたいてい一つ上の階層にあります――ファイルの中で以前に間違った名前をつけたものです。
このエラーが発生する原因
関数ではなく文字列に対して () を使って呼び出そうとしたとき、Pythonはこのエラーを発生させます。次の3つのケースで95%をカバーしています:
1. 組み込み関数を上書きした場合
str = "some value" # 変数名を 'str' にした
result = str(123) # Pythonは str をあなたの文字列として扱い、組み込み関数ではないと判断する
# TypeError: 'str' object is not callable
2. 文字列変数を関数として呼び出した場合
formatter = "Hello, {}"
output = formatter("world") # formatter は関数ではなく文字列
# TypeError: 'str' object is not callable
3. クラス属性がメソッドを上書きした場合
class Report:
def __init__(self):
self.generate = "pending" # 下のメソッドを上書きしてしまう
def generate(self):
return "report data"
r = Report()
r.generate() # TypeError: 'str' object is not callable
素早い診断方法
エラーが発生する行の直前にこの2行を追加してください:
print(type(your_variable)) # <class 'str'> と表示されれば、それが原因
print(callable(your_variable)) # False = 呼び出し不可
またはデバッガーでステップ実行することもできます:
import pdb; pdb.set_trace()
# プロンプトで: print(type(the_thing_you_called))
修正方法1: 上書きした変数名を変更する
Pythonの組み込み関数は予約語ではありません。str や list という名前の変数を作っても Python は止めてくれませんが、本来の組み込み関数に依存していた箇所が静かに壊れます。
壊れているコード:
str = "my string value"
num = 42
result = str(num) # クラッシュ — str はあなたの変数になっている
修正後:
my_str = "my string value"
num = 42
result = str(num) # 動作する — str() は組み込み関数に戻った
うっかり再利用しがちな他の組み込み名にも注意してください:list、dict、id、input、print、type、format、filter、map。これらはすべて合法的な変数名ですが、変数名として使うべきではありません。
対話型シェルで上書きした組み込み関数を元に戻す
str = "something" を実行した後の対話型シェルにいる場合は、変数を削除してください:
del str # 変数を削除
str(123) # '123' — 組み込み関数が復元された
修正方法2: 呼び出しの代わりに .format() か f-string を使う
文字列テンプレートは関数呼び出しではなく、.format() か f-string を使います。
壊れているコード:
greeting = "Hello, {}"
message = greeting("Alice") # TypeError
修正後:
# 方法1: .format()
message = greeting.format("Alice")
# 方法2: f-string(より簡潔)
name = "Alice"
message = f"Hello, {name}"
本来は関数にしたかった場合は、正しく定義してください:
def greeting(name):
return f"Hello, {name}"
message = greeting("Alice") # 動作する
修正方法3: 競合しているクラス属性の名前を変更する
__init__ で self.generate = "pending" と代入すると、そのインスタンスの generate メソッドが静かに置き換えられます。Pythonはクラスメソッドより先にインスタンス属性を参照するため、文字列が優先されて呼び出し時に失敗します。
壊れているコード:
class Report:
def __init__(self):
self.generate = "pending" # メソッドを破壊してしまう
def generate(self):
return "report data"
修正後:
class Report:
def __init__(self):
self.status = "pending" # 別の名前にすることで競合を回避
def generate(self):
return "report data"
r = Report()
r.generate() # 動作する
修正の確認
Pythonシェルで正常に戻っているか確認してください:
>>> str(42)
'42'
>>> callable(str)
True
>>> callable("some string")
False
すでにインポート済みのモジュール内で実行している場合は、Pythonプロセスを再起動してください。前回のインポート時の古い変数がモジュールの名前空間に残っている可能性があります。
再発を防ぐために
リンターを導入しましょう。pylint と flake8 はどちらも、組み込み関数の上書きを本番環境に届く前に検出してくれます:
pip install pylint
pylint your_script.py
# W0622: Redefining built-in 'str' (redefined-builtin)
Pylance を使った VS Code と PyCharm は、入力中にこれらの競合をインラインでハイライトしてくれます。一度設定しておけば、このクラスのバグを深夜ではなく数秒で発見できるようになります。
- pylint:
W0622 redefined-builtinとして警告 - flake8 + flake8-builtins:
A001 variable is shadowing a Python builtinとして警告 - Pyright / Pylance: エディター上で競合している名前をアンダーラインで表示
ほぼ常に命名の衝突が原因です。関数と同じ名前をつけてしまったものを見つけて名前を変えれば、TypeError: 'str' object is not callable は消えます。

