Python functools.update_wrapper Function

The functools.update_wrapper function in Python's functools module is used to update a wrapper function to look more like the wrapped function. This is particularly useful when writing decorators, as it helps preserve the metadata of the original function.

Table of Contents

  1. Introduction
  2. functools.update_wrapper Function Syntax
  3. Examples
    • Basic Usage
    • Using with a Simple Decorator
    • Customizing the Wrapper
  4. Real-World Use Case
  5. Conclusion

Introduction

When creating decorators, the metadata of the original function (such as its name, docstring, and module) is often lost. The functools.update_wrapper function helps copy these attributes from the original function to the wrapper function, making debugging and introspection easier.

functools.update_wrapper Function Syntax

Here is how you use the functools.update_wrapper function:

import functools

functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

Parameters:

  • wrapper: The function to be updated.
  • wrapped: The original function.
  • assigned: Optional. A tuple specifying which attributes of the original function are assigned directly to the wrapper function (default is WRAPPER_ASSIGNMENTS which includes __module__, __name__, __qualname__, __annotations__, and __doc__).
  • updated: Optional. A tuple specifying which attributes of the wrapper function are updated with the corresponding attributes from the original function (default is WRAPPER_UPDATES which includes __dict__).

Returns:

  • The wrapper function with updated attributes.

Examples

Basic Usage

Update a simple wrapper function to preserve the metadata of the original function.

Example

import functools

def original_function():
    """This is the original function."""
    pass

def wrapper_function():
    pass

functools.update_wrapper(wrapper_function, original_function)
print(wrapper_function.__name__)  # Output: original_function
print(wrapper_function.__doc__)   # Output: This is the original function.

Using with a Simple Decorator

Create a decorator that uses functools.update_wrapper to preserve the metadata of the decorated function.

Example

import functools

def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("Wrapper function")
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def my_function():
    """This is my function."""
    print("Original function")

print(my_function.__name__)  # Output: my_function
print(my_function.__doc__)   # Output: This is my function.

Customizing the Wrapper

Customize which attributes are updated by update_wrapper.

Example

import functools

def original_function():
    """This is the original function."""
    pass

def wrapper_function():
    pass

functools.update_wrapper(wrapper_function, original_function, assigned=('__doc__',))
print(wrapper_function.__name__)  # Output: wrapper_function
print(wrapper_function.__doc__)   # Output: This is the original function.

Real-World Use Case

Logging Decorator

Create a logging decorator that preserves the metadata of the decorated function.

Example

import functools

def logging_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@logging_decorator
def compute(x, y):
    """Compute the sum of x and y."""
    return x + y

print(compute(2, 3))         # Output: Calling compute
                             #         5
print(compute.__name__)      # Output: compute
print(compute.__doc__)       # Output: Compute the sum of x and y.

Conclusion

The functools.update_wrapper function is used for creating decorators that preserve the metadata of the original function. It helps maintain the integrity of function attributes such as the name, docstring, and module, which is important for debugging and introspection. Proper usage can enhance the readability and maintainability of decorated functions.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare