Functions as Objects in Python 2026
In Python, functions are first-class objects. This powerful feature allows you to treat functions like any other object — assign them to variables, pass them as arguments, return them from other functions, and store them in data structures. Understanding this concept is key to writing flexible and elegant code.
TL;DR — Key Takeaways 2026
- Functions can be assigned to variables, passed as arguments, and returned from other functions
- This enables powerful patterns like higher-order functions, callbacks, and decorators
- Use function attributes and closures for advanced behavior
- Functions as objects make code more modular and reusable
1. Basic Function as Object
def greet(name: str) -> str:
return f"Hello, {name}!"
# Functions are objects
say_hello = greet
print(say_hello("Alice")) # Hello, Alice!
# Pass function as argument
def execute(func, arg):
return func(arg)
print(execute(greet, "Bob")) # Hello, Bob!
2. Advanced Patterns – Higher-Order Functions
# Return a function from another function
def make_multiplier(factor: int):
def multiplier(x: int) -> int:
return x * factor
return multiplier
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(10)) # 20
print(triple(10)) # 30
# Using as callback
def process_data(data, processor):
return [processor(item) for item in data]
result = process_data([1, 2, 3, 4], lambda x: x * x)
3. Best Practices in 2026
- Use functions as first-class objects to create flexible APIs
- Pass functions as arguments for callbacks and strategy patterns
- Return functions to create closures and factory patterns
- Store functions in dictionaries for dynamic dispatch
- Combine with type hints for better IDE support and clarity
What It Means That Functions Are Objects
In Python a function is an object of type function, just like a list or a string is an object. It has attributes such as __name__, __doc__ and __defaults__, it can be stored in variables and containers, passed to other functions and returned from them.
This is often described as functions being first-class citizens. It is the basis for callbacks, sorting with key=, decorators, plugin registries and many pandas methods such as apply and agg, which all accept functions as arguments.
Because a function is an object, you can also inspect it at runtime. The inspect module reads its signature, and attributes like __module__ tell you where it was defined, which is useful for logging and debugging.
You can even attach your own attributes to a function, although a class or a closure is usually clearer for storing state.
Worked Example: Inspecting and Using a Function Object
We read a function's attributes and pass it to built-in functions that expect a function.
import inspect
def net_price(price: float, tax: float = 0.17) -> float:
"""Price including tax."""
return round(price * (1 + tax), 2)
print(type(net_price).__name__, net_price.__name__)
print(net_price.__doc__, net_price.__defaults__)
print(inspect.signature(net_price))
prices = [100, 40, 250]
print(list(map(net_price, prices)))
print(sorted(prices, key=net_price, reverse=True))
The object reports its type as function and its name as net_price, and shows the docstring and the default tax of 0.17. map applies it to every price, giving [117.0, 46.8, 292.5], and sorted uses it as a key.
Practical Tips
Use the inspect module when you build tools that call user-supplied functions. Checking the signature before calling gives a clear error message instead of a confusing TypeError deep in your code.
Remember that methods, built-in functions, classes and objects with a __call__ method are also callable. Code that accepts a function usually works with any of them, which keeps your helpers flexible.
Store function objects rather than their names as strings, so a typo is caught when the module loads.
Common Mistakes
- Writing net_price() when passing the function, which passes its result instead.
- Storing state in function attributes where a class would be clearer.
- Comparing functions by name instead of by identity.
- Forgetting that lambdas are function objects too, named <lambda>.
Quick Summary
- Functions are objects with attributes.
- They can be stored, passed and returned.
- inspect.signature reads parameters.
- Pass the function, not its result.
Conclusion
Treating functions as first-class objects is one of Python’s greatest strengths. In 2026, mastering this concept allows you to write more modular, reusable, and elegant code. From simple callbacks to complex decorator patterns, functions as objects unlock powerful design possibilities.
Next steps:
- Review your codebase and look for opportunities to use functions as objects