TL;DR
callable()は、呼び出し可能オブジェクトを判定する組み込み関数である。呼び出し可能オブジェクトとは、関数やメソッドのように () を付けて呼び出せるオブジェクトのことである。
callable() のポイント
- object 引数が呼び出し可能オブジェクトであれば True を返す
- クラスは呼び出し可能である
- 関数は呼び出し可能である
- インスタンスオブジェクトは呼び出しできないが
__call__()
を持つインスタンスは () を付けて呼び出せる- 関数が引数となる場合に使う
callable(object)
False のケース
呼び出し可能オブジェクトでない場合、False が返る。
x = 1
print(callable(x))
# False
クラスは 呼び出し可能オブジェクトなので True になるが、
class A:
def func(self):
pass
callable(A)
# True
インスタンスオブジェクトは False になる。
class A:
def func(self):
pass
a = A()
callable(a)
# False
しかし、特殊メソッド__call__()
を実装したインスタンスでは True を返す。__call__
を実装したクラスでは、インスタンスを関数のように呼び出すことができるようになる。しかしなぜ、関数のように呼び出し可能になるのだろうか?
class A:
def __call__(self):
pass
a = A()
callable(a)
# True
関数の中身を dir()で見ると、__call__
が含まれている。
def func():
pass
dir(func)
#['__annotations__',
# '__call__',
# '__class__',
# '__str__',
# '__subclasshook__']
これは、関数オブジェクトが __call__
を実装した function クラスのインスタンスであることを示している。
True のケース
関数
def a(x):
return x
callable(a)
# True
ラムダ関数
ラムダ関数も呼び出し可能な関数なので True となる。
callable(lambda x: x + 1)
# True
クラス
カスタムクラスは__call__
を実装すれば、関数のように呼び出し可能となるので True が返る。
class A:
def __call__(self):
pass
print(callable(A))
# True
クラスのメソッドも True になる。
class A:
def calc(self, x):
self.x = x
def talk(self):
print(self)
b = 'hoge'
a = A()
callable(A) # True
callable(a.calc) # True
callable(b) # False