5 Best Ways to Detect Whether a Python Variable is a Function

πŸ’‘ Problem Formulation: In Python programming, it’s often necessary to check whether a given variable holds a function. This can be critical when passing callable objects around or doing dynamic execution. Given a variable, we want to confidently assert if it’s a functionβ€”such as def my_func(): passβ€”or something else (e.g., my_var = 10).

Method 1: Using the callable() Built-in Function

In Python, the callable() function returns True if the object appears callable (i.e., it might be callable, not just a function) and False otherwise. Note that this will also return True for classes and instances with a __call__() method, in addition to functions.

Here’s an example:

def my_function():
    pass

print(callable(my_function)) # Should return True
print(callable(5)) # Should return False

The output of this code snippet will be:

True
False

The callable() function provides a quick check, but remember that not all callable objects are functions; some could be classes or objects with a __call__() method.

Method 2: Using the types Module

The types module in Python defines names for many object types, including FunctionType. You can compare the type of your variable with types.FunctionType to see if it is indeed a function.

Here’s an example:

import types

def my_function():
    pass

print(isinstance(my_function, types.FunctionType))

The output will be:

True

This is a specific test for functions, excluding other callable objects. It is reliable but requires an additional import from the types module.

Method 3: By Checking the __code__ Attribute

Every Python function has a __code__ attribute that contains its compiled byte code. You can check for the existence of this attribute to see if a variable is a function. However, this method is not as clear-cut, as other callables might also have a __code__ attribute.

Here’s an example:

def my_function():
    pass

has_code = hasattr(my_function, '__code__')
print(has_code)

The output will be:

True

This approach serves as a simple check but can yield false positives with other callable types, so it is not as foolproof as checking against types.FunctionType.

Method 4: Using the inspect Module

The inspect module provides several utilities for code introspection, including isfunction(), which returns True if the object is a user-defined function. This is probably the most precise method if you specifically want to target functions and not other callable objects.

Here’s an example:

import inspect

def my_function():
    pass

print(inspect.isfunction(my_function))

The output will manifest as:

True

Using the inspect module is straightforward and gives an accurate determination if a variable holds a user-defined function, though it does involve importing an additional module.

Bonus One-Liner Method 5: Using a Lambda with the type() Function

This one-liner involves using a lambda (an instance of a function) to verify if a given object is of the same type as a lambda, which is considered a function in Python.

Here’s an example:

def my_function():
    pass

is_function = lambda obj: type(obj) is type(lambda: None)
print(is_function(my_function))

The output will look like this:

True

This nifty one-liner can distinguish functions from other types of objects concisely without additional imports. However, it may not be immediately clear to readers unfamiliar with Python’s treatment of lambdas as function types.

Summary/Discussion

  • Method 1: callable(). Broad. May include non-function callables. Quick and built-in.
  • Method 2: types.FunctionType. Specific to functions. Requires import. Accurate for checking functions only.
  • Method 3: __code__ Attribute. Quick. Potential false positives. Not the most robust method.
  • Method 4: inspect.isfunction(). Precise. User-defined functions only. Requires import. Clear intent.
  • Bonus Method 5: Lambda with type(). Clever. No imports. May be unclear. Ensures exact function type.