Python __call__とは?インスタンスを関数のように呼ぶ特殊メソッド|__init__との違いと使いどころ
Pythonの__call__は、クラスに定義するとそのインスタンスを obj(引数) のように関数として呼び出せるようにする特殊メソッドです。設定や呼び出し回数などの「状態」を持った関数を作るときや、クラスで書くデコレータ、PyTorchのモデルのように「呼ぶと前後の処理も走る」仕組みに使われます。
この記事では、__call__の基本、__init__との違い、クロージャやfunctools.partialとの使い分け、クラスデコレータでの使い方、インスタンスに後から__call__を代入しても動かない理由までを、Python 3.12.15で実行した結果つきで説明します。
__call__の基本|インスタンスを関数のように呼ぶ
class Adder:
def __init__(self, n):
self.n = n
def __call__(self, x):
return x + self.n
add5 = Adder(5)
print(add5(10))
print(add5(100))
実行結果:
15
105
add5はクラスのインスタンスですが、add5(10)と関数のように呼べています。5という設定を内部に持ったまま、何度でも使えます。
公式ドキュメント(データモデル)には、__call__を定義するとx(arg1, arg2, ...)はおおよそtype(x).__call__(x, arg1, ...)に置き換えられると書かれています(2026年10月18日確認)。つまりadd5(10)は、内部的にはAdder.__call__(add5, 10)です。
__init__と__call__の違い|呼ばれるタイミング
初心者が最も混乱しやすいのがこの2つの違いです。__init__はクラス名()でインスタンスを作るときに1回、__call__はできたインスタンスをインスタンス()で呼ぶたびに実行されます。
class Demo:
def __init__(self):
print("__init__ が呼ばれた")
def __call__(self):
print("__call__ が呼ばれた")
d = Demo() # クラスを呼ぶ
d() # インスタンスを呼ぶ
d()
実行結果:
__init__ が呼ばれた
__call__ が呼ばれた
__call__ が呼ばれた
__init__ |
__call__ |
|
|---|---|---|
| 呼ばれる書き方 | Demo()(クラスを呼ぶ) |
d()(インスタンスを呼ぶ) |
| 呼ばれる回数 | インスタンス生成時に1回 | 呼ぶたびに何回でも |
| 役割 | 初期設定を属性に保存する | 保存した設定を使って処理する |
| 戻り値 | Noneでなければならない |
自由 |
「__init__で設定を覚え、__call__でそれを使う」のが基本の組み合わせです。
定義しないと「object is not callable」になる
class NoCall:
pass
n = NoCall()
print(callable(n))
n()
実行結果:
False
Traceback (most recent call last):
File "<string>", line 6, in <module>
TypeError: 'NoCall' object is not callable
callable()で、呼び出せるかどうかを事前に判定できます。なお「’list’ object is not callable」のようなエラーの多くは__call__とは関係なく、list = [1, 2, 3]のように組み込み関数の名前を変数で上書きしたことが原因です。callable()の使い方はPython「callable()」の使い方で詳しく説明しています。
インスタンスに__call__を代入しても動かない
公式ドキュメントのとおり、()で呼んだときに探されるのはクラス(type(x))の__call__です。インスタンスの属性として後から入れても使われません。
class Plain:
pass
p = Plain()
p.__call__ = lambda: "hello"
print(p.__call__())
print(callable(p))
実行結果:
hello
False
p.__call__()と明示すれば動きますが、p()とは書けません。インスタンスごとに呼んだときの動きを変えたいなら、__call__はクラスに定義し、その中で属性に入れた関数を呼びます。
使いどころ1:呼び出しをまたいで状態を保つ
class Counter:
def __init__(self):
self.count = 0
def __call__(self):
self.count += 1
return self.count
c = Counter()
print(c(), c(), c())
print("呼ばれた回数:", c.count)
c.count = 0 # 外からリセットできる
print(c())
実行結果:
1 2 3
呼ばれた回数: 3
1
呼び出し回数をc.countで外から読んだりリセットしたりできるのが、普通の関数との違いです。
クロージャ・partialとの使い分け
同じことはクロージャ(関数の中で関数を返す書き方)でもできます。
def make_counter():
count = 0
def counter():
nonlocal count
count += 1
return count
return counter
c2 = make_counter()
print(c2(), c2(), c2())
実行結果:
1 2 3
引数を固定するだけならfunctools.partialが最も短く書けます。
| やりたいこと | 向いている書き方 | 理由 |
|---|---|---|
| 引数を固定するだけ | functools.partial |
1行で書ける |
| 小さな状態を1つ持つ | クロージャ | クラスを作るより短い |
| 状態を外から読む・リセットする | __call__ |
属性として素直に見える |
| 呼び出し以外のメソッドも持たせる | __call__ |
クラスなのでreset()なども足せる |
使いどころ2:設定を持った関数としてmap・sortedに渡す
class ByDistance:
def __init__(self, origin):
self.origin = origin
def __call__(self, x):
return abs(x - self.origin)
nums = [3, 10, 7, 1, 8]
print(sorted(nums, key=ByDistance(7)))
print(list(map(ByDistance(5), nums)))
実行結果:
[7, 8, 10, 3, 1]
[2, 5, 2, 4, 3]
「関数を受け取る場所」にはそのまま渡せます。型ヒントではCallable[[int], int]として扱えます(Python Callableとは?参照)。
使いどころ3:クラスで書くデコレータ
デコレータは「関数を受け取り、呼び出せるものを返す」仕組みなので、__call__を持つクラスがそのまま使えます。functools.update_wrapper()を使うと、元の関数名なども引き継げます。
import functools
class CountCalls:
def __init__(self, func):
functools.update_wrapper(self, func)
self.func = func
self.n = 0
def __call__(self, *args):
self.n += 1
return self.func(*args)
@CountCalls
def hello(name):
"""あいさつを返す"""
return f"hi, {name}"
print(hello("A"))
print(hello("B"))
print("呼び出し回数:", hello.n)
print(hello.__name__, hello.__doc__)
実行結果:
hi, A
hi, B
呼び出し回数: 2
hello あいさつを返す
関数で書くデコレータと違い、回数などの状態を属性としてそのまま持てるのが利点です。関数で書くデコレータはPythonのデコレータとは?、名前の引き継ぎはfunctools.wrapsの使い方で解説しています。
使いどころ4:呼ぶと前後の処理も走る仕組み(PyTorchのモデル)
身近な例がPyTorchです。モデルはforward()に計算を書きますが、使うときはmodel(x)とインスタンスを呼びます。PyTorchの公式ドキュメント(torch.nn.Module)では、forward()を直接呼ぶのではなくモジュールのインスタンスを呼ぶべきで、そうしないと登録したフック(前後の処理)が実行されないと説明されています(2026年10月18日確認、2.14のドキュメント)。
同じ考え方を標準ライブラリだけで再現すると、次のようになります。
class Module:
def __init__(self):
self.hooks = []
def __call__(self, x):
y = self.forward(x)
for hook in self.hooks:
hook(x, y)
return y
class Double(Module):
def forward(self, x):
return x * 2
m = Double()
m.hooks.append(lambda x, y: print(f"入力 {x} → 出力 {y}"))
print(m(3))
print(m.forward(4)) # 直接呼ぶとフックは動かない
実行結果:
入力 3 → 出力 6
6
8
__call__に共通の前後処理を書き、子クラスはforward()だけを書く、という役割分担です。__call__が「インスタンスを呼んだときの入口」になっていることがわかります。
__call__のまとめ
| ポイント | 内容 |
|---|---|
| 役割 | インスタンスを()で呼べるようにする |
__init__との違い |
__init__は生成時に1回、__call__は呼ぶたび |
| 定義しないと | TypeError: '…' object is not callable |
| 判定 | callable(obj)(クラス自体もTrue) |
| 探される場所 | クラス側。インスタンスに代入しても()では使われない |
| 主な用途 | 状態を持つ関数、sortedのkey、クラスデコレータ、前後処理の共通化 |
ほかの特殊メソッド(__add__や__eq__など)の書き方は演算子オーバーロードと特殊メソッドの解説にまとめています。
よくある質問
Q. Pythonの__call__とは何ですか?
クラスに定義すると、そのインスタンスを obj(引数) のように関数として呼び出せるようにする特殊メソッドです。obj(10) は内部的に type(obj).__call__(obj, 10) として実行されます。
Q. __init__と__call__の違いは?
__init__はクラス名()でインスタンスを作るときに1回だけ呼ばれ、初期設定を保存します。__call__はできたインスタンスを呼ぶたびに実行され、保存した設定を使って処理します。
Q. __call__はどんなときに使いますか?
呼び出し回数や設定などの状態を持った関数を作るとき、sortedのkeyやmapに設定付きの関数を渡すとき、クラスでデコレータを書くとき、PyTorchのモデルのように呼ぶと前後の処理も実行させたいときに使います。
Q. インスタンスに後から__call__を代入すると呼べますか?
呼べません。()で呼んだときに探されるのはクラス側の__call__なので、インスタンスの属性に入れても callable() は False のままです。
Q. クロージャやfunctools.partialとどう使い分けますか?
引数を固定するだけならpartial、小さな状態を1つ持つだけならクロージャが短く書けます。状態を外から読んだりリセットしたりしたい、ほかのメソッドも持たせたい場合は__call__を持つクラスが向いています。



