How to Check If a Function Is a Generator in Python
In Python, generators are a special category of functions that allow you to declare a function that behaves like an iterator. Instead of returning a single value and exiting, they allow you to yield a series of values over time, pausing execution between each one. This makes them highly memory-efficient for large datasets.
However, because generators are defined using the standard def keyword, it is not always immediately obvious if a function is a standard function or a generator. This guide explains how to programmatically distinguish between the two.
Understanding Functions vs. Generators
Before checking types, it is important to understand the behavioral difference.
- Regular Function: Runs to completion and returns a single result (which could be a list). It holds all data in memory.
- Generator Function: Returns a "generator iterator" immediately. It executes code only when values are requested (lazy evaluation).
# Regular Function
def get_squares_list(numbers):
result = []
for n in numbers:
result.append(n * n)
return result
# Generator Function
def get_squares_gen(numbers):
for n in numbers:
yield n * n
# Calling them
nums = [1, 2, 3]
print(f"Function returns: {type(get_squares_list(nums))}")
print(f"Generator returns: {type(get_squares_gen(nums))}")
Output:
Function returns: <class 'list'>
Generator returns: <class 'generator'>
Method 1: Using inspect.isgeneratorfunction() (Recommended)
If you have the function object itself (the definition) and want to know if it will behave as a generator when called, the standard inspect module provides the most robust tool.
inspect.isgeneratorfunction(obj) returns True if the object is a Python generator function.
import inspect
def my_regular_func():
return "Hello"
def my_generator_func():
yield "Hello"
# ✅ Correct: Inspecting the function objects directly
is_reg_gen = inspect.isgeneratorfunction(my_regular_func)
is_gen_gen = inspect.isgeneratorfunction(my_generator_func)
print(f"Is 'my_regular_func' a generator? {is_reg_gen}")
print(f"Is 'my_generator_func' a generator? {is_gen_gen}")
Output:
Is 'my_regular_func' a generator? False
Is 'my_generator_func' a generator? True
This method is preferred because it checks the function definition without actually running the code or creating an instance of the generator.
Method 2: Checking the Result Object
Sometimes you don't have access to the function definition, but you have the result of a function call. You need to know if that result is a generator iterator.
For this, you use inspect.isgenerator().
import inspect
def number_gen():
yield 1
yield 2
# 1. Call the function to get the result object
gen_object = number_gen()
# 2. Check the object type
# ⛔️ Incorrect: isgeneratorfunction() returns False for the object instance
print(f"Is object a function? {inspect.isgeneratorfunction(gen_object)}")
# ✅ Correct: isgenerator() checks the instance returned by the call
print(f"Is object a generator? {inspect.isgenerator(gen_object)}")
Output:
Is object a function? False
Is object a generator? True
Key Distinction:
isgeneratorfunction(f)checks the blueprint (thedef).isgenerator(f())checks the house built from the blueprint (the returned iterator).
The Role of the yield Keyword
Syntactically, the defining characteristic of a generator in Python is the use of yield. If a function contains yield anywhere in its body, Python treats it as a generator.
import inspect
# A function returning a list (Not a generator)
def return_list():
return [1, 2, 3]
# A function yielding items (Is a generator)
def yield_items():
yield 1
yield 2
yield 3
print(f"Has yield? {inspect.isgeneratorfunction(yield_items)}")
print(f"Only return? {inspect.isgeneratorfunction(return_list)}")
Output:
Has yield? True
Only return? False
Conclusion
To determine if a function is a generator:
- Use
inspect.isgeneratorfunction(func)if you are checking the function definition itself. - Use
inspect.isgenerator(obj)if you are checking the return value of a function call. - Look for
yield: Any function containingyieldis automatically a generator.