How do I detect whether a Python variable is a function? – Dev

The best answers to the question “How do I detect whether a Python variable is a function?” in the category Dev.


I have a variable, x, and I want to know whether it is pointing to a function or not.

I had hoped I could do something like:

>>> isinstance(x, function)

But that gives me:

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'function' is not defined

The reason I picked that is because

>>> type(x)
<type 'function'>


Builtin types that don’t have constructors in the built-in namespace (e.g. functions, generators, methods) are in the types module. You can use types.FunctionType in an isinstance call:

>>> import types
>>> types.FunctionType
<class 'function'>

>>> def f(): pass

>>> isinstance(f, types.FunctionType)
>>> isinstance(lambda x : None, types.FunctionType)

Note that this uses a very specific notion of “function” that is usually not what you need. For example, it rejects zip (technically a class):

>>> type(zip), isinstance(zip, types.FunctionType)
(<class 'type'>, False)

open (built-in functions have a different type):

>>> type(open), isinstance(open, types.FunctionType)
(<class 'builtin_function_or_method'>, False)

and random.shuffle (technically a method of a hidden random.Random instance):

>>> type(random.shuffle), isinstance(random.shuffle, types.FunctionType)
(<class 'method'>, False)

If you’re doing something specific to types.FunctionType instances, like decompiling their bytecode or inspecting closure variables, use types.FunctionType, but if you just need an object to be callable like a function, use callable.


If this is for Python 2.x or for Python 3.2+, you can use callable(). It used to be deprecated, but is now undeprecated, so you can use it again. You can read the discussion here: You can do this with:


If this is for Python 3.x but before 3.2, check if the object has a __call__ attribute. You can do this with:

hasattr(obj, '__call__')

The oft-suggested types.FunctionTypes or inspect.isfunction approach (both do the exact same thing) comes with a number of caveats. It returns False for non-Python functions. Most builtin functions, for example, are implemented in C and not Python, so they return False:

>>> isinstance(open, types.FunctionType)
>>> callable(open)

so types.FunctionType might give you surprising results. The proper way to check properties of duck-typed objects is to ask them if they quack, not to see if they fit in a duck-sized container.


The accepted answer was at the time it was offered thought to be correct. As it
turns out, there is no substitute for callable(), which is back in Python
3.2: Specifically, callable() checks the tp_call field of the object being
tested. There is no plain Python equivalent. Most of the suggested tests are
correct most of the time:

>>> class Spam(object):
...     def __call__(self):
...         return 'OK'
>>> can_o_spam = Spam()

>>> can_o_spam()
>>> callable(can_o_spam)
>>> hasattr(can_o_spam, '__call__')
>>> import collections
>>> isinstance(can_o_spam, collections.Callable)

We can throw a monkey-wrench into this by removing the __call__ from the
class. And just to keep things extra exciting, add a fake __call__ to the instance!

>>> del Spam.__call__
>>> can_o_spam.__call__ = lambda *args: 'OK?'

Notice this really isn’t callable:

>>> can_o_spam()
Traceback (most recent call last):
TypeError: 'Spam' object is not callable

callable() returns the correct result:

>>> callable(can_o_spam)

But hasattr is wrong:

>>> hasattr(can_o_spam, '__call__')

can_o_spam does have that attribute after all; it’s just not used when calling
the instance.

Even more subtle, isinstance() also gets this wrong:

>>> isinstance(can_o_spam, collections.Callable)

Because we used this check earlier and later deleted the method, abc.ABCMeta
caches the result. Arguably this is a bug in abc.ABCMeta. That said,
there’s really no possible way it could produce a more accurate result than
the result than by using callable() itself, since the typeobject->tp_call
slot method is not accessible in any other way.

Just use callable()


Since Python 2.1 you can import isfunction from the inspect module.

>>> from inspect import isfunction
>>> def f(): pass
>>> isfunction(f)
>>> isfunction(lambda x: x)