I am trying to properly type hint my code and encountered both Callable and FunctionType
from typing import Callable
def my_func() -> Callable:
f = lambda: _
return f
result = my_func()
type(result) # <class 'function'>
isinstance(result, Callable) # True
vs
from types import FunctionType
def my_func() -> FunctionType
f = lambda: ...
return f
result = my_func()
type(result) # <class 'function'>
isinstance(result, FunctionType) # True
One possible case I can think of is to distinguish between regular and class-based callables like this
class C:
def __call__(self):
pass
def my_func() -> Callable:
c = C()
return c
result = my_func()
type(result) # <class 'function'>
isinstance(result, Callable) # True
isinstance(result, FunctionType) # False
What are the differences between those and when I have to use one over the other?
types.FunctionType
is dynamically defined in cpython/Lib/types.py#L11-L12 as the type of the simplest function.typing.Callable
on the other hand is defined as a wrappedcollections.abc.Callable
which a) should be used directly if using python >= 3.9 and b) is itself defined in cpython/Lib/_collections_abc.py#L534-L548 as something having a__call__
method.You have highlighted correctly that nearly anything can be a callable, just need to give it a
__call__
method, on the other hand, a class will never be a function.You should use
Callable
in most cases unless you are completely certain you need a function only.Moreover, you can (and should) type the arguments and return value of
Callable
, for instance:Callable[[], None]
-- no arg, returnsNone
(e.g.lambda: None
)Callable[[int, int], int]
-- twoint
args, returns anint
Callable[..., None]
-- any arg, returnsNone
, (e.g.print
).