views:

210

answers:

9

Since functions are values in Python, how do I determine if the variable is a function?

For example:

boda = len   # boda is the length function now
if ?is_var_function(boda)?:
  print "Boda is a function!"
else:
  print "Boda is not a function!"

Here hypothetical ?is_var_function(x)? should return true if x is a callable function, and false if it is not.

Please advise!

Thanks, Boda Cydo.

+4  A: 

There is a callable function in python.

 if callable(boda):
kgrad
A function/method is every object which implements a `__call__` method. callable() is a good way to test for the existence of such a call method.
tux21b
But callable will also return true for a class, won't it? It's not clear if the OP also wanted that.
Javier Badia
I suspect the OP doesn't know the difference, and actually does want anything callable. Chances are good that if you don't know how to check if something's a function in Python, you don't actually want to be doing it.
Glenn Maynard
+1  A: 

Use callable(boda) to determine whether boda is callable or not.

Callable means here being a function, method or even a class. But since you want to distinguish only between variables and functions it should work nicely.

Your code would then look like:

boda = len   # boda is the length function now
if callable(boda):
  print "Boda is a function!"
else:
  print "Boda is not a function!"
pajton
A: 

It's not a 100% perfect solution, but you might want to check out the "callable" built-in function:

http://docs.python.org/library/functions.html

Brent Nash
The perfect solution being, of course, nothing.
Mike Graham
+1  A: 
>>> import types
>>> def f(): pass
...
>>> x = 0
>>> type(f) == types.FunctionType
True
>>> type(x) == types.FunctionType
False

That will check if it's a function. callable() will check if it's callable (that is, it has a __call__ method), so it will return true on a class as well as a function or method.

Javier Badia
`isinstance` is generally preferred for typechecking. `is` is generally preferred over `==` for checking singletons. Requiring a function and not something else that acts exactly like a function is a bad policy.
Mike Graham
`type(sys.exit) == types.FunctionType` and `type((1.0).hex) == types.FunctionType` are both false. (It still fails with isinstance; I don't know why BuiltinFunctionType and MethodType aren't subclasses of FunctionType.)
Glenn Maynard
+8  A: 

You may use inspect.isfunction(object). See: docs.python.org

That said, you should avoid using this technique in your day-to-day code. Sometimes you actually need to use reflection - for example, an MVC framework might need to load a class and inspect its members. But usually you should return/pass/deal with objects that have the same "interface". For example, do not return an object that may be an integer or a function - always return the same "type" of object so your code can be consistent.

Justin Ethier
@Justin Ethier - looks like someone downvoted every answer.
kgrad
It provides advice on how to do something that is usually bad without context on how to build good, robust, idiomatic Python code.
Mike Graham
It also happens to answer the question, which is the purpose of this site.
harto
Helping people, providing good advice, and contributing to better programs are all superior goals to answering questions.
Mike Graham
I hope the purpose of this site is *not* to blindly answer questions even when it's very likely that the person is asking the wrong one. Answering the question anyway is fine (he really might want what he says he wants, and it's maddening to ask a question and to have everyone refuse to answer it--which does happen), but a good answer should follow up with an explanation of why it's probably not what he wants.
Glenn Maynard
Site philosophy aside, this answer is incorrect. inspect.isfunction(sys.exit) and inspect.isfunction((1.0).hex) are both false (builtins and bound methods).
Glenn Maynard
(minor correction: (1.0).hex is a BuiltinFunction and not a MethodFunction; but isfunction is still false for bound methods.)
Glenn Maynard
+6  A: 

The callable built-in mentioned in other answers doesn't answer your question as posed, because it also returns True, besides functions, for methods, classes, instances of classes which define a __call__ method. If your question's title and text are wrong, and you don't care if something is in fact a function but only if it's callable, then use that builtin. But the best answer to your question as posed is: import the inspect method of Python's standard library, and use inspect.isfunction. (There are other, lower-abstraction ways, but it's always a good idea to use functionality of the inspect module for introspection when it's there, in preference to lower-level approaches: inspect helps keep your code concise, clear, robust, and future-proof).

Alex Martelli
Another wrong answer accepted on SO. I should start a list. This fails for builtin functions and class methods, as I mentioned in a couple other answers. You'd need to also check inspect.isbuiltin() and inspect.ismethod(), and there's nothing "future-proof" about having that many special cases.
Glenn Maynard
A: 

And what should it return for a property, which you access like a value attribute but actually invokes a function? Your seemingly simple question actually opens up a whole can of worms in Python. Which means things like callable and isfunction are good to know about for your education and introspection, but are probably not things you want to rely on when interfacing with other code.

Tangentially: See the Turtles All The Way Down presentation for more on how Python is put together.

keturn
A property is a strange example. Properties don't act very much like functions and, more to the point, in a normal situation you don't access the actual property object, you'd access the object it got for you.
Mike Graham
A: 

The philosophy of how to use different objects in a Python program is called duck typing—if it looks like a duck, quacks like duck, and walks like a duck, it's a duck. Objects are grouped not by what their type is but what they are capable of doing, and this even extends to functions. When writing a Python program, you should always know what all your objects can do and use them without checking.

For example, I could define a function

def add_three(a, b c):
    return a + b + c

and mean for it to be used with three floats. But by not checking this, I have a much more useful function—I can use it with ints, with decimal.Decimals, or with fractions.Fractions, for example.

The same applies to having a function. If I know I have a function and want to call it, I should just call it. Maybe what I have is a function and maybe I have a different callable (like a bound method or an instance of an arbitrary class that defines __call__) that could be just as good. By not checking anything, I make my code able to handle a wide range of circumstances I might not even have thought of in advance.

In the case of callables, I can pretty reliably determine whether I have one or not, but for the sake of my code's simplicity, I shouldn't want to. If someone passes in something that's not callable, you'll get an error when you call it anyways. If I'm writing code that accepts a parameter that may be a callable or not and I do different things depending on it, it sounds like I should improve my API by defining two functions to do these two different things.

If you did have a way to handle the case where the caller passed in something that isn't function-like (and this wasn't just the result of an insane API), the right solution would be to catch the TypeError that is raised when you try to call something that can't be called. In general, it's better to try to do something and recover if it fails rather than to check ahead of time. (Recall the cliché, "It's easier to ask forgiveness than permission.") Checking ahead of time can lead to unexpected problems based on subtle errors in logic and can lead to race conditions.

Why do you think you need to typecheck?

Mike Graham
A: 

If you want to exclude class methods, you have to be aware of the difference between a function and a built-in function.

import types

if isinstance(yourfunc, types.FunctionType) or isinstance(yourfunc, types.BuiltinFunctionType):
    "You have a function"

But in most cases I expect you just want to know if you have a callable.

mikerobi
why the downvote?
mikerobi
It's a useful answer, but to a different question.
dkagedal
@dkagedal how does it not answer the question?
mikerobi
I removed the downvote.
dkagedal