How to check for a function type in Python?
Asked Answered
I

4

14

I've got a list of things, of which some can also be functions. If it is a function I would like to execute it. For this I do a type-check. This normally works for other types, like str, int or float. But for a function it doesn't seem to work:

>>> def f():
...     pass
... 
>>> type(f)
<type 'function'>
>>> if type(f) == function: print 'It is a function!!'
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'function' is not defined
>>>

Does anybody know how I can check for a function type?

Ingle answered 12/7, 2013 at 10:19 Comment(1)
You can also use try/except instead of checking for type.Blackberry
F
19

Don't check types, check actions. You don't actually care if it's a function (it might be a class instance with a __call__ method, for example) - you just care if it can be called. So use callable(f).

Fidelfidela answered 12/7, 2013 at 10:21 Comment(0)
V
5
import types

if type(f) == types.FunctionType: 
    print 'It is a function!!'
Vernievernier answered 11/9, 2013 at 9:12 Comment(0)
E
4

Because function isn't a built-in type, a NameError is raised. If you want to check whether something is a function, use hasattr:

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

Or you can use isinstance():

>>> from collections import Callable
>>> isinstance(f, Callable)
True
>>> isinstance(map, Callable)
True
Enthral answered 12/7, 2013 at 10:21 Comment(7)
isinstance is not good for isinstance(map, types.FunctionType) returns False. Builtin functions are different not to mention the callable class.Polygamy
@Polygamy For built-in functions, you can use inspect.isbuiltinEnthral
There is collections.Callable. It works for buitlin functions too: isinstance(map, collections.Callable) returns TrueBoddie
@Boddie - What's the difference between collections.Callable and simply callable (as suggested by DanielRoseman)?Ingle
@Ingle well, i think it just another solution. callable() looks like more simplier.Boddie
@Ingle I did some research, it looks like callable was considered deprecated, and was actually removed in python 3.0 as it was suggested to use collections.Callable. However, it was put back in in 3.1Enthral
@Ingle callable is a built-in function. collections.Callable is an abstract base class for classes that provide the __call__() method. I don't see any reason to use the latter for this purpose.Blackberry
B
3

collections.Callable can be used:

import collections

print isinstance(f, collections.Callable)
Boddie answered 12/7, 2013 at 10:37 Comment(1)
And in new-ish Python 3 versions (I think it's 3.2+) callable is re-introduced as a shorthand for this.Pill

© 2022 - 2024 — McMap. All rights reserved.