951

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'>
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Daniel H
  • 9,895
  • 3
  • 19
  • 11
  • 58
    I'm depressed by the number of answers working around the problem by looking for some __call__ attribute or callable function... A clean way is about type(a) == types.functionType as suggested by @ryan – AsTeR Sep 20 '13 at 12:09
  • 63
    @AsTeR 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 "compare it directly" approach will give the wrong answer for many functions, like builtins. – John Feminella Jun 02 '14 at 16:58
  • 4
    @JohnFeminella While I agree with you in principle. The OP didn't ask if it was callable, just if it is a function. Perhaps it could be argued that he needed a distinction between, for example, functions and classes? – McKay Feb 28 '17 at 18:15
  • 4
    For my purposes, I came here because I wanted to use `insepct.getsource` on a variety of objects, and it actually matters not whether the object was callable but whether it was something that would give 'function' for `type(obj)`. Since google led me here, I'd say AsTeR's comment was the most useful answer (for me). There are plenty of other places on the internet for people to discover `__call__` or `callable`. – tsbertalan Dec 07 '17 at 21:23
  • 9
    @AsTeR It is types.FunctionType, with a capital F. – Ben Mares Nov 08 '19 at 17:32
  • @BenMares I can't edit anymore, but thanks for noticing! – AsTeR Nov 11 '19 at 14:09
  • @AsTeR Yeep clean way but that kind of depends on the person reading on the internet, their choice :) glad Ryan brought it up. – Ice Bear Dec 19 '20 at 12:03
  • 1
    Use ```inspect.isfunction(object)``` which is present in inspect module. – Sathvik Feb 10 '21 at 19:31

30 Answers30

1192

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: http://bugs.python.org/issue10518. You can do this with:

callable(obj)

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)
False
>>> callable(open)
True

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.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • 105
    This also won't tell you if it's a function--just if it can be called. – Chris B. Mar 09 '09 at 04:02
  • 30
    Depends on the application whether the distinction matters or not; I suspect you're right that it doesn't for the original question, but that's far from certain. – Chris B. Mar 09 '09 at 05:33
  • 9
    Classes can have a __call__ function attached to it. So this is definitely not a good method for distinguishing. Ryan's method is better. – Brian Bruggeman Dec 02 '11 at 20:12
  • 54
    the "duck typing" concept makes this the better answer, e.g. "what does it matter if it's a function as long as it behaves like one?" – jcomeau_ictx Jan 02 '12 at 04:02
  • 3
    Sometimes though, duck typing has its limitations. – sebpiq Jun 04 '12 at 08:26
  • 5
    Sometimes you HAVE to distinguish, "give me the function name or class name of the request handler" – Chris Jun 26 '13 at 14:18
  • 3
    @staticmethods versus instancemethods break every answer on this page (as of this writing) except this one. The OP was wise to choose this as his preferred response. – Craig Labenz Jun 29 '13 at 19:44
  • 10
    There are usecases where the distinction between a callable and a function is crucial, for example when writing a decorator (see my comment on Ryan's answer). – Turion Dec 06 '13 at 22:26
  • 1
    This doesn't work for classmethods... which don't have a `__call__` method but nonetheless I happen to be interested in catching – Brian Peterson Jun 08 '15 at 21:41
  • `callable(module)` and `hasattr(module, '__call__')` both disregard that sockets and other things are callable however are *NOT* functions. If you try: except: for example, you now have a callable attribute within a module in some circumstances (i.e. with socket's gaierror, which is how I came accross this). USE `from types import FuntionType` then `isinstance(attr, FunctionType)` as is mentioned in the other answer. – dylnmc Oct 07 '15 at 04:47
  • `>>> class FOO(object): def __call__(self, msg): print(msg) >>> f = FOO() >>> hasattr(f, '__call__') # true >>> isinstance(f, types.FunctionType) # False`. types.FunctionType is the answer! – GoingMyWay Sep 01 '16 at 07:35
  • 1
    `types.FunctionType` fails in many cases you would (presumably) want it to pass, like builtins -- e.g. `isinstance(open, types.FunctionType)` is `False`. The correct answer is still `callable()` if you can use it. As I wrote earlier: "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 "compare it directly" approach will give the wrong answer for many functions, like builtins." – John Feminella Sep 02 '16 at 08:44
  • 1
    Nitpick: Checking *"if they fit in a duck-sized container"* is duck-typing. You're checking they have the size of a duck, not checking that they are actually a duck. – Carl Smith May 04 '18 at 03:03
  • How is this answer still correct? It doesn't distinct class from function, so it doesn't answer the question. @JohnFeminella I think it worth mentioning this in the answer. – Eugene K Jul 03 '20 at 16:12
  • 1
    @EugeneK it does answer for some :) – Ice Bear Dec 19 '20 at 11:58
  • @IceBear answering to some doesn't make it a correct answer, but rather misleading. Callable !== function, duck typing !== detect type – Eugene K Oct 05 '21 at 16:37
  • @EugeneK there's no clear definition for function in the python docs. https://docs.python.org/3/reference/datamodel.html#types The question doesn't ask for "User-defined functions". `callable` is the only thing there that encompasses *User-defined functions* and other things like `abs()` that are also clearly functions (`type(abs) -> `). So the practical answer to the question is actually the correct one. – Benjamin Atkin Jun 16 '22 at 02:39
336

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)
True
>>> isinstance(lambda x : None, types.FunctionType)
True

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.

Gringo Suave
  • 29,931
  • 6
  • 88
  • 75
Ryan
  • 15,016
  • 6
  • 48
  • 50
  • 7
    +1 answering the question. However, trying to guess whether an object is a function — or even if it is any callable object — is usually a mistake. Without further information from the OP it's difficult to dismiss it out of hand of course, but still... – bobince Mar 09 '09 at 04:49
  • 50
    It will actually return False for builtin functions, like 'open' for eg. So to be specific you will have to use isinstance(f, (types.FunctionType, types.BuiltinFunctionType)). And of course if you strictly want just functions, not callables nor methods. – Lukasz Korzybski Apr 20 '11 at 14:06
  • 5
    @ŁukaszKorzybski and to be more precdise... you should also check for functools.partial: `isinstance(f, (types.FunctionType, types.BuiltinFunctionType, functools.partial))` or checking `f.func` in such a case. – estani Jan 17 '13 at 12:04
  • 3
    @bobince, how about this usecase: I want to write a decorator `@foo` that I can use both as `@foo` and as `@foo(some_parameter)`. It then needs to check what it is being called with, e.g. the function to decorate (first case) or the parameter (the second case, in which it needs to return a further decorator). – Turion Dec 06 '13 at 22:24
  • `types.BuiltinFunctionType` is also the type of ("normal") built-in *methods*, which you probably don't want to allow, if you're not going the `callable` route. – user2357112 Nov 12 '18 at 19:42
105

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

>>> from inspect import isfunction
>>> def f(): pass
>>> isfunction(f)
True
>>> isfunction(lambda x: x)
True
Vebjorn Ljosa
  • 17,438
  • 13
  • 70
  • 88
Paolo
  • 20,112
  • 21
  • 72
  • 113
  • 3
    Nice, but it seems to return False for builtin functions like `open` and `hasattr`. – Zecc May 04 '13 at 19:43
  • 14
    @Zecc [isbuiltin](http://docs.python.org/2/library/inspect.html#inspect.isbuiltin) is for that. – Paolo May 05 '13 at 07:16
  • 15
    See the `inspect.isfunction` docstring: *"Return true if the object is a user-defined function."* – Mark Mikofski Aug 06 '13 at 20:27
  • 5
    Note that 'isfunction' does not recognize functool.partial functions. – ishmael Dec 05 '13 at 19:16
  • 3
    The [entire source code](https://github.com/python/cpython/blob/00e24cdca422f792b80016287562b6b3bccab239/Lib/inspect.py#L159-L170) of `isfunction` is `return isinstance(object, types.FunctionType)` so it comes with the caveats pointed out in [@Ryan's answer](https://stackoverflow.com/a/624948). – Boris Verkhovskiy Jan 23 '21 at 21:24
86

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()
'OK'
>>> callable(can_o_spam)
True
>>> hasattr(can_o_spam, '__call__')
True
>>> import collections
>>> isinstance(can_o_spam, collections.Callable)
True

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)
False

But hasattr is wrong:

>>> hasattr(can_o_spam, '__call__')
True

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)
True

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()

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • 7
    Amazing illustration of the pitfalls of `hasattr(o, '__call__')` approach and why `callable()`, if available, is superior. – MestreLion Jan 30 '15 at 07:52
  • To be fair, the correct use of `hasattr` would check `type(o)`, not `o` itself, and you can just as easily fool `callable` by patching `Spam.__call__` instead of shadowing it with an instance attribute. Set `Spam.__call__ = 3`, and `callable(Spam())` still returns `True`. Ultimately, the only definitive test for when an object is callable is to try calling it. – chepner Mar 07 '23 at 20:16
54

The following should return a boolean:

callable(x)
Nikhil
  • 5,705
  • 1
  • 32
  • 30
  • 1
    That solves his problem, but he's still created a mystery: if x is of class 'function' in module __builtin__, and help(x.__class__) describes "class function", why is "function" apparently "not defined"? – Ken Mar 09 '09 at 03:52
  • 2
    "function" isn't a keyword or a built-in type. The type of functions is defined in the "types" module, as "types.FunctionType" – Chris B. Mar 09 '09 at 04:03
36

Result

callable(x) hasattr(x, '__call__') inspect.isfunction(x) inspect.ismethod(x) inspect.isgeneratorfunction(x) inspect.iscoroutinefunction(x) inspect.isasyncgenfunction(x) isinstance(x, typing.Callable) isinstance(x, types.BuiltinFunctionType) isinstance(x, types.BuiltinMethodType) isinstance(x, types.FunctionType) isinstance(x, types.MethodType) isinstance(x, types.LambdaType) isinstance(x, functools.partial)
print × × × × × × × × ×
func × × × × × × × ×
functools.partial × × × × × × × × × ×
<lambda> × × × × × × × ×
generator × × × × × × ×
async_func × × × × × × ×
async_generator × × × × × × ×
A × × × × × × × × × × ×
meth × × × × × × × ×
classmeth × × × × × × × × ×
staticmeth × × × × × × × ×
import types
import inspect
import functools
import typing


def judge(x):
    name = x.__name__ if hasattr(x, '__name__') else 'functools.partial'
    print(name)
    print('\ttype({})={}'.format(name, type(x)))
    print('\tcallable({})={}'.format(name, callable(x)))
    print('\thasattr({}, \'__call__\')={}'.format(name, hasattr(x, '__call__')))
    print()
    print('\tinspect.isfunction({})={}'.format(name, inspect.isfunction(x)))
    print('\tinspect.ismethod({})={}'.format(name, inspect.ismethod(x)))
    print('\tinspect.isgeneratorfunction({})={}'.format(name, inspect.isgeneratorfunction(x)))
    print('\tinspect.iscoroutinefunction({})={}'.format(name, inspect.iscoroutinefunction(x)))
    print('\tinspect.isasyncgenfunction({})={}'.format(name, inspect.isasyncgenfunction(x)))
    print()
    print('\tisinstance({}, typing.Callable)={}'.format(name, isinstance(x, typing.Callable)))
    print('\tisinstance({}, types.BuiltinFunctionType)={}'.format(name, isinstance(x, types.BuiltinFunctionType)))
    print('\tisinstance({}, types.BuiltinMethodType)={}'.format(name, isinstance(x, types.BuiltinMethodType)))
    print('\tisinstance({}, types.FunctionType)={}'.format(name, isinstance(x, types.FunctionType)))
    print('\tisinstance({}, types.MethodType)={}'.format(name, isinstance(x, types.MethodType)))
    print('\tisinstance({}, types.LambdaType)={}'.format(name, isinstance(x, types.LambdaType)))
    print('\tisinstance({}, functools.partial)={}'.format(name, isinstance(x, functools.partial)))


def func(a, b):
    pass


partial = functools.partial(func, a=1)

_lambda = lambda _: _


def generator():
    yield 1
    yield 2


async def async_func():
    pass


async def async_generator():
    yield 1


class A:
    def __call__(self, a, b):
        pass

    def meth(self, a, b):
        pass

    @classmethod
    def classmeth(cls, a, b):
        pass

    @staticmethod
    def staticmeth(a, b):
        pass


for func in [print,
             func,
             partial,
             _lambda,
             generator,
             async_func,
             async_generator,
             A,
             A.meth,
             A.classmeth,
             A.staticmeth]:
    judge(func)

Time

Pick the three most common methods:

time/s
callable(x) 0.86
hasattr(x, '__call__') 1.36
isinstance(x, typing.Callable) 12.19
import typing
from timeit import timeit


def x():
    pass


def f1():
    return callable(x)


def f2():
    return hasattr(x, '__call__')


def f3():
    return isinstance(x, typing.Callable)


print(timeit(f1, number=10000000))
print(timeit(f2, number=10000000))
print(timeit(f3, number=10000000))
# 0.8643081
# 1.3563508
# 12.193492500000001
Lutz Prechelt
  • 36,608
  • 11
  • 63
  • 88
XerCis
  • 917
  • 7
  • 6
  • Don't forget too, the tuple argument version of isinstance. For example: `isinstance(x, (types.BuiltinFunctionType, types.BuiltinMethodType, types.FunctionType, types.MethodType, types.LambdaType, functools.partial))` – frogstarr78 Sep 03 '22 at 08:05
26

Python's 2to3 tool (http://docs.python.org/dev/library/2to3.html) suggests:

import collections
isinstance(obj, collections.Callable)

It seems this was chosen instead of the hasattr(x, '__call__') method because of http://bugs.python.org/issue7006.

Gary van der Merwe
  • 9,134
  • 3
  • 49
  • 80
nh2
  • 24,526
  • 11
  • 79
  • 128
  • 1
    It's also mentioned in the bug report about bringing back `callable()` for py3.3: https://bugs.python.org/issue10518#msg122309 – luckydonald Aug 19 '18 at 07:56
19

callable(x) will return true if the object passed can be called in Python, but the function does not exist in Python 3.0, and properly speaking will not distinguish between:

class A(object):
    def __call__(self):
        return 'Foo'

def B():
    return 'Bar'

a = A()
b = B

print type(a), callable(a)
print type(b), callable(b)

You'll get <class 'A'> True and <type function> True as output.

isinstance works perfectly well to determine if something is a function (try isinstance(b, types.FunctionType)); if you're really interested in knowing if something can be called, you can either use hasattr(b, '__call__') or just try it.

test_as_func = True
try:
    b()
except TypeError:
    test_as_func = False
except:
    pass

This, of course, won't tell you whether it's callable but throws a TypeError when it executes, or isn't callable in the first place. That may not matter to you.

Chris B.
  • 85,731
  • 25
  • 98
  • 139
  • 9
    Calling it is a bad idea. What if it has side-effects, or actually does something but takes a really long time? – asmeurer May 15 '13 at 22:01
  • @asmeurer - Why else would you need to know if it's a function if you're not calling it? – detly Jun 06 '13 at 06:22
  • 1
    @detly: for debugging I regularly want to print all variables in an object, the methods are usually not useful to me so I wouldn't want to execute them. In the end I just list every non-callable property with the corresponding values :) – Wolph Jun 06 '13 at 07:39
  • 2
    Just because *you're* not calling it doesn't mean it's not being called. Maybe you're doing dispatch. – asmeurer Jun 06 '13 at 13:52
  • 4
    There's a big problem with using exceptions to know whether it was callable or not; what if it *is* callable, but calling it raises an exception you're looking for? You'll both silently ignore an error *and* misdiagnose whether it was callable. When you're using EAFP you really want to avoid putting too much in the try, but there's no way to do that for this use case. – Ben Sep 09 '13 at 21:03
  • Hey - it *does* exist in py3 – Mr_and_Mrs_D Nov 17 '21 at 07:04
16

If you want to detect everything that syntactically looks like a function: a function, method, built-in fun/meth, lambda ... but exclude callable objects (objects with __call__ method defined), then try this one:

import types
isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.BuiltinMethodType, types.UnboundMethodType))

I compared this with the code of is*() checks in inspect module and the expression above is much more complete, especially if your goal is filtering out any functions or detecting regular properties of an object.

Marcin Wojnarski
  • 2,362
  • 24
  • 17
  • 1
    Thank you for pointing me to the `types` module. I was testing a `make_stemmer()` factory that would sometimes return a function and sometimes a callable `Stemmer` instance, and I needed to detect the difference. – hobs Mar 22 '16 at 16:24
15

Try using callable(x).

Excerpt:

Return True if the object argument appears callable, False if not.

Paolo
  • 20,112
  • 21
  • 72
  • 113
maxyfc
  • 11,167
  • 7
  • 37
  • 46
9

If you have learned C++, you must be familiar with function object or functor, means any object that can be called as if it is a function.

In C++, an ordinary function is a function object, and so is a function pointer; more generally, so is an object of a class that defines operator(). In C++11 and greater, the lambda expression is the functor too.

Similarity, in Python, those functors are all callable. An ordinary function can be callable, a lambda expression can be callable, a functional.partial can be callable, the instances of class with a __call__() method can be callable.


Ok, go back to question : I have a variable, x, and I want to know whether it is pointing to a function or not.

If you want to judge weather the object acts like a function, then the callable method suggested by @John Feminella is ok.

If you want to judge whether a object is just an ordinary function or not( not a callable class instance, or a lambda expression), then the xtypes.XXX suggested by @Ryan is a better choice.

Then I do an experiment using those code:

#!/usr/bin/python3
# 2017.12.10 14:25:01 CST
# 2017.12.10 15:54:19 CST

import functools
import types
import pprint

Define a class and an ordinary function.

class A():
    def __call__(self, a,b):
        print(a,b)
    def func1(self, a, b):
        print("[classfunction]:", a, b)
    @classmethod
    def func2(cls, a,b):
        print("[classmethod]:", a, b)
    @staticmethod
    def func3(a,b):
        print("[staticmethod]:", a, b)

def func(a,b):
    print("[function]", a,b)

Define the functors:

#(1.1) built-in function
builtins_func = open
#(1.2) ordinary function
ordinary_func = func
#(1.3) lambda expression
lambda_func  = lambda a : func(a,4)
#(1.4) functools.partial
partial_func = functools.partial(func, b=4)

#(2.1) callable class instance
class_callable_instance = A()
#(2.2) ordinary class function
class_ordinary_func = A.func1
#(2.3) bound class method
class_bound_method = A.func2
#(2.4) static class method
class_static_func = A.func3

Define the functors' list and the types' list:

## list of functors
xfuncs = [builtins_func, ordinary_func, lambda_func, partial_func, class_callable_instance, class_ordinary_func, class_bound_method, class_static_func]
## list of type
xtypes = [types.BuiltinFunctionType, types.FunctionType, types.MethodType, types.LambdaType, functools.partial]

Judge wether the functor is callable. As you can see, they all are callable.

res = [callable(xfunc)  for xfunc in xfuncs]
print("functors callable:")
print(res)

"""
functors callable:
[True, True, True, True, True, True, True, True]
"""

Judge the functor's type( types.XXX). Then the types of functors are not all the same.

res = [[isinstance(xfunc, xtype) for xtype in xtypes] for xfunc in xfuncs]

## output the result
print("functors' types")
for (row, xfunc) in zip(res, xfuncs):
    print(row, xfunc)

"""
functors' types
[True, False, False, False, False] <built-in function open>
[False, True, False, True, False] <function func at 0x7f1b5203e048>
[False, True, False, True, False] <function <lambda> at 0x7f1b5081fd08>
[False, False, False, False, True] functools.partial(<function func at 0x7f1b5203e048>, b=4)
[False, False, False, False, False] <__main__.A object at 0x7f1b50870cc0>
[False, True, False, True, False] <function A.func1 at 0x7f1b5081fb70>
[False, False, True, False, False] <bound method A.func2 of <class '__main__.A'>>
[False, True, False, True, False] <function A.func3 at 0x7f1b5081fc80>
"""

I draw a table of callable functor's types using the data.

enter image description here

Then you can choose the functors' types that suitable.

such as:

def func(a,b):
    print("[function]", a,b)

>>> callable(func)
True
>>> isinstance(func,  types.FunctionType)
True
>>> isinstance(func, (types.BuiltinFunctionType, types.FunctionType, functools.partial))
True
>>> 
>>> isinstance(func, (types.MethodType, functools.partial))
False
Community
  • 1
  • 1
Kinght 金
  • 17,681
  • 4
  • 60
  • 74
8

As the accepted answer, John Feminella stated that:

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 "compare it directly" approach will give the wrong answer for many functions, like builtins.

Even though, there're two libs to distinguish functions strictly, I draw an exhaustive comparable table:

8.9. types — Dynamic type creation and names for built-in types — Python 3.7.0 documentation

30.13. inspect — Inspect live objects — Python 3.7.0 documentation

#import inspect             #import types
['isabstract',
 'isasyncgen',              'AsyncGeneratorType',
 'isasyncgenfunction', 
 'isawaitable',
 'isbuiltin',               'BuiltinFunctionType',
                            'BuiltinMethodType',
 'isclass',
 'iscode',                  'CodeType',
 'iscoroutine',             'CoroutineType',
 'iscoroutinefunction',
 'isdatadescriptor',
 'isframe',                 'FrameType',
 'isfunction',              'FunctionType',
                            'LambdaType',
                            'MethodType',
 'isgenerator',             'GeneratorType',
 'isgeneratorfunction',
 'ismethod',
 'ismethoddescriptor',
 'ismodule',                'ModuleType',        
 'isroutine',            
 'istraceback',             'TracebackType'
                            'MappingProxyType',
]

The "duck typing" is a preferred solution for general purpose:

def detect_function(obj):
    return hasattr(obj,"__call__")

In [26]: detect_function(detect_function)
Out[26]: True
In [27]: callable(detect_function)
Out[27]: True

As for the builtins function

In [43]: callable(hasattr)
Out[43]: True

When go one more step to check if builtin function or user-defined funtion

#check inspect.isfunction and type.FunctionType
In [46]: inspect.isfunction(detect_function)
Out[46]: True
In [47]: inspect.isfunction(hasattr)
Out[47]: False
In [48]: isinstance(detect_function, types.FunctionType)
Out[48]: True
In [49]: isinstance(getattr, types.FunctionType)
Out[49]: False
#so they both just applied to judge the user-definded

Determine if builtin function

In [50]: isinstance(getattr, types.BuiltinFunctionType)
Out[50]: True
In [51]: isinstance(detect_function, types.BuiltinFunctionType)
Out[51]: False

Summary

Employ callable to duck type checking a function,
Use types.BuiltinFunctionType if you have further specified demand.

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138
7

An Exact Function Checker

callable is a very good solution. However, I wanted to treat this the opposite way of John Feminella. Instead of treating it like this saying:

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 "compare it directly" approach will give the wrong answer for many functions, like builtins.

We'll treat it like this:

The proper way to check if something is a duck is not to see if it can quack, but rather to see if it truly is a duck through several filters, instead of just checking if it seems like a duck from the surface.

How Would We Implement It

The 'types' module has plenty of classes to detect functions, the most useful being types.FunctionType, but there are also plenty of others, like a method type, a built in type, and a lambda type. We also will consider a 'functools.partial' object as being a function.

The simple way we check if it is a function is by using an isinstance condition on all of these types. Previously, I wanted to make a base class which inherits from all of the above, but I am unable to do that, as Python does not allow us to inherit from some of the above classes.

Here's a table of what classes can classify what functions:

Functions table from kinght-金 Above function table by kinght-金

The Code Which Does It

Now, this is the code which does all of the work we described from above.

from types import BuiltinFunctionType, BuiltinMethodType,  FunctionType, MethodType, LambdaType
from functools import partial

def is_function(obj):
  return isinstance(obj, (BuiltinFunctionType, BuiltinMethodType,  FunctionType, MethodType, LambdaType, partial))

#-------------------------------------------------

def my_func():
  pass

def add_both(x, y):
  return x + y

class a:
  def b(self):
    pass

check = [

is_function(lambda x: x + x),
is_function(my_func),
is_function(a.b),
is_function(partial),
is_function(partial(add_both, 2))

]

print(check)
>>> [True, True, True, False, True]

The one false was is_function(partial), because that's a class, not a function, and this is exactly functions, not classes. Here is a preview for you to try out the code from.

Conclusion

callable(obj) is the preferred method to check if an object is a function if you want to go by duck-typing over absolutes.

Our custom is_function(obj), maybe with some edits is the preferred method to check if an object is a function if you don't any count callable class instance as a function, but only functions defined built-in, or with lambda, def, or partial.

And I think that wraps it all up. Have a good day!

Community
  • 1
  • 1
Corman
  • 749
  • 11
  • 16
6

Here's a couple of other ways:

def isFunction1(f) :
    return type(f) == type(lambda x: x);

def isFunction2(f) :
    return 'function' in str(type(f));

Here's how I came up with the second:

>>> type(lambda x: x);
<type 'function'>
>>> str(type(lambda x: x));
"<type 'function'>"
# Look Maa, function! ... I ACTUALLY told my mom about this!
pb2q
  • 58,613
  • 19
  • 146
  • 147
Sumukh Barve
  • 1,414
  • 15
  • 12
  • This is nice! Should work on all version of python2.x and python3.x! – Saurav Kumar Apr 26 '18 at 19:31
  • If you look at the `types` module, `types.FunctionType` is actually defined simply by defining a trivial function and using `type` to return its type. The second one is easily broken by using a metaclass that includes the word `function` in its string representation. – chepner Mar 07 '23 at 20:20
5

A function is just a class with a __call__ method, so you can do

hasattr(obj, '__call__')

For example:

>>> hasattr(x, '__call__')
True

>>> x = 2
>>> hasattr(x, '__call__')
False

That is the "best" way of doing it, but depending on why you need to know if it's callable or note, you could just put it in a try/execpt block:

try:
    x()
except TypeError:
    print "was not callable"

It's arguable if try/except is more Python'y than doing if hasattr(x, '__call__'): x().. I would say hasattr is more accurate, since you wont accidently catch the wrong TypeError, for example:

>>> def x():
...     raise TypeError
... 
>>> hasattr(x, '__call__')
True # Correct
>>> try:
...     x()
... except TypeError:
...     print "x was not callable"
... 
x was not callable # Wrong!
dbr
  • 165,801
  • 69
  • 278
  • 343
  • Use exception handling to protect against unexpected behavior only, never for logic flow--that is definitely not Pythonic. – gotgenes Mar 09 '09 at 05:49
  • Well, hasattr basically does a getattr in a try/except block (albeit in C). http://blog.jancewicz.net/2007/10/reflection-hasattr.html – dbr Mar 09 '09 at 07:22
  • @dbr: But hasattr is more aesthetic. – Nikhil Mar 09 '09 at 20:53
4

Instead of checking for '__call__' (which is not exclusive to functions), you can check whether a user-defined function has attributes func_name, func_doc, etc. This does not work for methods.

>>> def x(): pass
... 
>>> hasattr(x, 'func_name')
True

Another way of checking is using the isfunction() method from the inspect module.

>>> import inspect
>>> inspect.isfunction(x)
True

To check if an object is a method, use inspect.ismethod()

Stefan van den Akker
  • 6,661
  • 7
  • 48
  • 63
4

Since classes also have __call__ method, I recommend another solution:

class A(object):
    def __init__(self):
        pass
    def __call__(self):
        print 'I am a Class'

MyClass = A()

def foo():
    pass

print hasattr(foo.__class__, 'func_name') # Returns True
print hasattr(A.__class__, 'func_name')   # Returns False as expected

print hasattr(foo, '__call__') # Returns True
print hasattr(A, '__call__')   # (!) Returns True while it is not a function
guneysus
  • 6,203
  • 2
  • 45
  • 47
4

Note that Python classes are also callable.

To get functions (and by functions we mean standard functions and lambdas) use:

import types

def is_func(obj):
    return isinstance(obj, (types.FunctionType, types.LambdaType))


def f(x):
    return x


assert is_func(f)
assert is_func(lambda x: x)
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
3

Whatever function is a class so you can take the name of the class of instance x and compare:


if(x.__class__.__name__ == 'function'):
     print "it's a function"
Katsu
  • 1,868
  • 4
  • 19
  • 28
2

The solutions using hasattr(obj, '__call__') and callable(.) mentioned in some of the answers have a main drawback: both also return True for classes and instances of classes with a __call__() method. Eg.

>>> import collections
>>> Test = collections.namedtuple('Test', [])
>>> callable(Test)
True
>>> hasattr(Test, '__call__')
True

One proper way of checking if an object is a user-defined function (and nothing but a that) is to use isfunction(.):

>>> import inspect
>>> inspect.isfunction(Test)
False
>>> def t(): pass
>>> inspect.isfunction(t)
True

If you need to check for other types, have a look at inspect — Inspect live objects.

1

You could try this:

if obj.__class__.__name__ in ['function', 'builtin_function_or_method']:
    print('probably a function')

or even something more bizarre:

if "function" in lower(obj.__class__.__name__):
    print('probably a function')
tinnick
  • 316
  • 1
  • 2
  • 15
1

combining @Sumukh Barve, @Katsu and @tinnick 's answers, and if your motive is just to grab the list of builtin functions available for your disposal in the console, these two options work:

  1. [i for i, j in __builtin__.__dict__.items() if j.__class__.__name__ in ['function', 'builtin_function_or_method']]
  2. [i for i, j in __builtin__.__dict__.items() if str(j)[:18] == '<built-in function']
r_hudson
  • 193
  • 8
1

In Python3 I came up with type (f) == type (lambda x:x) which yields True if f is a function and False if it is not. But I think I prefer isinstance (f, types.FunctionType), which feels less ad hoc. I wanted to do type (f) is function, but that doesn't work.

dandan78
  • 13,328
  • 13
  • 64
  • 78
Aaron
  • 11
  • 1
0

Following previous replies, I came up with this:

from pprint import pprint

def print_callables_of(obj):
    li = []
    for name in dir(obj):
        attr = getattr(obj, name)
        if hasattr(attr, '__call__'):
            li.append(name)
    pprint(li)
Jabba
  • 19,598
  • 6
  • 52
  • 45
0

it is my code:

# -*- coding: utf-8 -*-
import hashlib
import inspect

# calc everything to md5!!
def count_md5(content):
    if isinstance(content, dict):
        return count_md5(
            [(str(k), count_md5(content[k])) for k in sorted(content.keys())],
        )
    elif isinstance(content, (list, tuple)):
        content = [count_md5(k) for k in content]
    elif callable(content):
        return make_callable_hash(content)
    return calc_md5(str(content))


def calc_md5(content):
    m2 = hashlib.md5()
    if isinstance(content, str):
        m2.update(content.encode("utf8"))
    else:
        m2.update(content)
    return m2.hexdigest()


def make_callable_hash(content):
    if inspect.isclass(content):
        h = []
        for attr in [i for i in sorted(dir(content)) if not i.startswith("__")]:
            v = getattr(content, attr)
            h.append(count_md5(v))

        return calc_md5("".join(h))

    return calc_md5(content.__name__)

For callable, most of the time we just want to see if the values of the attributes are consistent, so we can take all the attributes of the callable and evaluate it. 'callable' will return true if it's a class, so it's not very rigorous

ChenDehua
  • 95
  • 1
  • 5
-1

If the code will go on to perform the call if the value is callable, just perform the call and catch TypeError.

def myfunc(x):
  try:
    x()
  except TypeError:
    raise Exception("Not callable")
Roger Dahl
  • 15,132
  • 8
  • 62
  • 82
-1

The following is a "repr way" to check it. Also it works with lambda.

def a():pass
type(a) #<class 'function'>
str(type(a))=="<class 'function'>" #True

b = lambda x:x*2
str(type(b))=="<class 'function'>" #True
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vova
  • 563
  • 8
  • 20
-1

With isinstance() and type() which are both built-in functions in Python below, you can check if it's a function so you don't need to import anything:

def test():
    pass

print(isinstance(test, type(test)))

Output:

True
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
-2

This works for me:

str(type(a))=="<class 'function'>"
Josh Lee
  • 171,072
  • 38
  • 269
  • 275
  • 1
    And what does that tell us if the result is an empty string? For a function, I get `""`, for an integer, I get `""`, so I don't see how it's working for you :/ – pawamoy Apr 29 '19 at 14:55
  • Now only works for Python 3 :) Also depending on the original intent of the question, it would be incomplete: should the builtin `open` be considered a function? `str(type(open))` gives `` in Python 3. – pawamoy Apr 29 '19 at 15:07
-4

You can DIY a short function to check if the input is not string and cast the input to string will return matched name define:

def isFunction(o):return not isinstance(o,str) and str(o)[:3]=='<fu';

I think that this code is already compatible cross all python version.

Or if something change, you may add extra convert to lower case and check for content length. The format string casted of function I saw is "<function "+name+" at 0xFFFFFFFF>"

phnghue
  • 1,578
  • 2
  • 10
  • 9
  • This is not very pythonic... and the output is subject to change if the string representation ever changes. – pmalbu Sep 01 '22 at 04:54
  • I think that the suitable solution for you is callable(x) or hasattr(x, '__call__') or inspect.isfunction(x) . Honestly I agree my function will fail if the string change. This question problem have many cases. My case is distinguis between class and function and without import other module, in limit file size. All accepted answer by other did not worked for me and some are deprecated in my python version. – phnghue Sep 01 '22 at 11:02