Python : __call__()は、インスタンスを関数のように扱う

TwitterFacebookHatena
  • 公開:2021-8-27
  • 更新:2023-10-26
  • 文章量:1007
  • Python

TL;DR

特殊メソッドである__call__はインスタンスを関数オブジェクトとして扱う。__call__を実装したクラスでは、インスタンスを関数のように呼び出すことができる。

__call__ のポイント

  • インスタンスを関数のように呼び出すことができる
  • 関数を呼び出すよりスマートな書き方になる

関数の中身を dir()で見ると、__call__ が含まれている。

def func():
    pass

dir(func)

#['__annotations__',
# '__call__',
# '__class__',
# '__str__',
# '__subclasshook__']

これは、関数オブジェクトが __call__ を実装した function クラスのインスタンスであることを示している。

通常、インスタンスを関数のように扱うとエラーが出る。

class A:
    def __init__(self):
        print('init')

a = A() # init
a() # エラーになる

次に__call__をつけてみると、インスタンスを関数のように扱うことができるようになる。

class A:
    def __init__(self):
        print('init')
    def __call__(self):
        print('call')

a = A() # init
a() # call

インスタンス、__call__、関数を比較。__call__を使うことで、関数を呼び出すよりスマートな書き方になる。

class A:
    def __init__(self, x):
        self.x = x
        print(f'{x} init')
    def __call__(self, y):
        self.y = y
        print(f'{self.x + y} call')
    def func(self, z):
        self.z = z
        print(f'{self.x + z} func')

a = A(1) # 1 init
a.func(2) # 3 func
a(2) # 3 call

Python : __call__()は、インスタンスを関数のように扱う