19

Am I correct assuming that all functions (built-in or user-defined) belong to the same class, but that class doesn't seem to be bound to any variable by default?

How can I check that an object is a function?

I can do this I guess:

def is_function(x):
  def tmp()
    pass
  return type(x) is type(tmp)

It doesn't seem neat, and I'm not even 100% sure it's perfectly correct.

max
  • 49,282
  • 56
  • 208
  • 355

4 Answers4

26

in python2:

callable(fn)

in python3:

isinstance(fn, collections.Callable)

as Callable is an Abstract Base Class, this is equivalent to:

hasattr(fn, '__call__')
dan_waterworth
  • 6,261
  • 1
  • 30
  • 41
  • 12
    The `callable` function was first removed in Python 3.0 and then brought back in Python 3.2 - so you can also use it w/ Python 3 if using a recent version of the interpreter. See http://docs.python.org/3/library/functions.html?highlight=callable#callable for more information. – Gerald Senarclens de Grancy Nov 18 '13 at 14:46
5

How can I check that an object is a function?

Isn't this same as checking for callables

hasattr(object, '__call__')

and also in python 2.x

callable(object) == True
pyfunc
  • 65,343
  • 15
  • 148
  • 136
  • 1
    it also applies to classes, but +1 anyway has it seems more in the logic of duck typing – kriss Nov 17 '10 at 07:28
3

You can do:

def is_function(x):
    import types
    return isinstance(x, types.FunctionType) \
        or isinstance(x, types.BuiltinFunctionType)
Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
-4
try:
    magicVariable()
except TypeError as e:
    print( 'was no function' )
poke
  • 369,085
  • 72
  • 557
  • 602
  • 7
    -1, you shouldn't have to execute the function to test it. – dan_waterworth Nov 17 '10 at 08:24
  • 4
    My code is not meant as a *test*. When you have a variable, the only reason why you would check if it is a function is because you want to use it. So instead of investing time in checking that beforehand, you should just use it as a function and handle the exception. – poke Nov 17 '10 at 08:26
  • 1
    i +1'ed it because in the general case, I think you're right but there are definitely cases where one wants to know if one is dealing with a function without having any intent of executing it. Metaclasses and class decorators come to mind. – aaronasterling Nov 17 '10 at 08:31
  • 1
    @poke: no, that is one reason. What if you want store the function? If you use this method it will be much more difficult to debug. – dan_waterworth Nov 17 '10 at 08:31
  • 2
    This doesn't work if the function raises a TypeError. – dan_waterworth Nov 17 '10 at 08:42
  • @dan_waterworth, I missed that. Now I wish I could undo my +1 – aaronasterling Nov 17 '10 at 08:44
  • @dan_waterworth: Okay, fair enough, but it's still a viable possibilty for a lot situations.. – poke Nov 17 '10 at 08:49
  • @aaronasterling: join the queue, there's a lot of votes I wish I could undo after people's comments. – dan_waterworth Nov 17 '10 at 08:50
  • sure, there are some situations where this works fine, but I happen to think that using callable or isinstance is more readable. – dan_waterworth Nov 17 '10 at 08:53
  • There are other reasons why you'd want to see if it is a function without executing it, but that code fragment does apply to many use cases. One problem is if the function through a type error inside of itself, it would report that it is not a function. – Chris Dutrow Mar 18 '13 at 01:54
  • Doesn't work if the function takes at least one argument, in which case, calling it on zero arguments will cause a separate `TypeError` – inspectorG4dget Oct 19 '13 at 15:04
  • I like this as a EAFP/LBYL solution. Do OP need to check, or just recover from doing and failing? – Chad Miller Sep 15 '15 at 17:31