Back to results for “Logging”
Python › Functions & Scope

How would you implement a function that dynamically inspects its own call arguments at runtime using the 'inspect' module, useful for building generic validation or logging decorators?

Advanced

Answer

inspect.signature(func).bind(*args, **kwargs) maps the ACTUAL passed arguments to their corresponding PARAMETER NAMES (correctly handling positional, keyword, defaults, *args, and **kwargs), letting you build generic tooling (like validation or logging) that needs to reason about arguments BY NAME regardless of how the caller actually passed them.
import inspect

def log_arguments(func):
    sig = inspect.signature(func)
    def wrapper(*args, **kwargs):
        bound = sig.bind(*args, **kwargs)
        bound.apply_defaults()
        print(f"Called with: {dict(bound.arguments)}")
        return func(*args, **kwargs)
    return wrapper

@log_arguments
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

greet("Sam")  # logs: {'name': 'Sam', 'greeting': 'Hello'}
Real-world example Building a generic argument-logging or validation decorator that correctly maps ANY call style (positional or keyword) back to parameter names.

Common follow-ups: What does bound.apply_defaults() specifically add that raw sig.bind() alone wouldn't include?