Functions as Arguments in Python 2026

Writing Functions Mar 16, 2026

Functions as Arguments in Python 2026

Passing functions as arguments to other functions is one of the most powerful and commonly used patterns in Python. It enables higher-order functions, callbacks, decorators, strategy patterns, and much more flexible code.

TL;DR — Key Takeaways 2026

  • You can pass any function as an argument just like any other object
  • This pattern is the foundation of callbacks, event handlers, and strategy design
  • Use Callable from typing for clear type hints
  • Keep passed functions pure when possible for predictable behavior

1. Basic Example


def greet(name: str) -> str:
    return f"Hello, {name}!"

def shout(text: str) -> str:
    return text.upper() + "!!!"

def process_message(message: str, formatter):
    """formatter is a function passed as argument."""
    formatted = formatter(message)
    print(formatted)

process_message("hello world", greet)   # Hello, hello world
process_message("hello world", shout)   # HELLO WORLD!!!

2. Real-World Higher-Order Function


from typing import Callable, List

def apply_to_all(items: List[int], operation: Callable[[int], int]) -> List[int]:
    """Apply any function to every item in the list."""
    return [operation(item) for item in items]

def square(x: int) -> int:
    return x * x

def double(x: int) -> int:
    return x * 2

numbers = [1, 2, 3, 4, 5]

print(apply_to_all(numbers, square))   # [1, 4, 9, 16, 25]
print(apply_to_all(numbers, double))   # [2, 4, 6, 8, 10]

3. Best Practices in 2026

  • Use descriptive parameter names (e.g., processor, formatter, callback)
  • Add proper type hints with Callable[[ArgTypes], ReturnType]
  • Document what arguments the passed function should accept and what it should return
  • Prefer small, focused functions when passing them as arguments
  • Combine with lists or dictionaries of functions for even more flexibility

Higher-Order Functions in Data Work

A function that takes another function as an argument is called a higher-order function. Python's built-ins map, filter, sorted, min and max are examples, and pandas offers many more, such as Series.apply, DataFrame.agg and groupby().transform.

Passing a function lets the caller decide the behaviour while the higher-order function handles the structure, such as looping, grouping or error handling. This separates what to do from how to repeat it.

When writing your own, document what the function argument must accept and return. A type hint such as Callable[[float], float] makes the contract clear and lets type checkers catch mistakes.

Prefer named functions over long lambdas, because named functions have readable tracebacks and can be tested on their own.

Worked Example: A Retry Helper That Takes a Function

We write a helper that calls any function and retries it when it raises a specific error.

from typing import Callable

def retry(func: Callable[[], float], attempts: int = 3) -> float:
    for n in range(1, attempts + 1):
        try:
            return func()
        except ValueError as e:
            print(f"attempt {n} failed: {e}")
    raise RuntimeError("all attempts failed")

readings = iter(["n/a", "bad", "21.5"])

def read_sensor() -> float:
    return float(next(readings))

print(retry(read_sensor))

The first two readings cannot be converted, so two attempts fail with a ValueError message. The third returns 21.5. The retry logic knows nothing about sensors, so it can be reused for any function that may raise ValueError.

Practical Tips

When a pandas method accepts a function, check whether a built-in vectorised method does the same job. Methods like .str.lower() or .sum() are much faster than apply with a Python function, because they run in optimised code.

Keep the passed function free of side effects where possible. A function that only computes a result can be reused, tested and run in parallel safely.

Name parameters that take functions clearly, such as transform or on_error, so callers know what to pass.

Return values rather than printing inside passed functions, so results stay reusable.

Common Mistakes

  • Passing func() instead of func.
  • Catching every exception and hiding real bugs.
  • Long lambdas that are hard to read and test.
  • Not documenting what the passed function must return.

Quick Summary

  • Higher-order functions take functions as arguments.
  • They separate behaviour from structure.
  • Use Callable hints to document the contract.
  • Prefer named functions to long lambdas.

Conclusion

Passing functions as arguments is a cornerstone of modern Python programming. In 2026, this technique allows you to write highly reusable, modular, and extensible code. From simple data processing to complex event-driven systems, functions as arguments unlock powerful design patterns.

Next steps:

  • Look for repetitive code that can be replaced by passing different functions as arguments

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices