Menu

Sign in to track your progress and unlock all features.

Theme style

Log in

Full lesson preview

Build a Decorator That Logs Arguments

Create a decorator that records each call's positional and keyword arguments. Learn to use functools.wraps and attach metadata to the wrapped function.

Python practice8 minDecorators FundamentalsBeginnerLast updated April 15, 2026

Problem statement

Decorators can add behavior to existing functions without modifying them. In this exercise you'll write a decorator named log_args that does two things: - Wraps any function and preserves its metadata (use functools.wraps). - On each call, appends a string describing the positional and keyword arguments to a list attached to the decorated function as .log, then returns the original function's result. The log entry format should be exactly: "args=<args_tuple>, kwargs=<kwargs_dict>" where <args_tuple> and <kwargs_dict> are the standard Python representations of the tuple of positional arguments and dictionary of keyword arguments respectively. Examples: - Calling add(2, 3) should produce the log entry: "args=(2, 3), kwargs={}". - Calling power(2, exp=5) should produce: "args=(2,), kwargs={'exp': 5}". You must support any signature (positional, keyword, defaults, varargs). The decorated function should expose the .log attribute (a list) that accumulates these strings across calls.

Task

Implement a decorator @log_args that appends a readable representation of the called arguments (args and kwargs) to a .log list on the decorated function every time it's called.

Examples

Basic usage

Input

@log_args\ndef add(a, b):\n return a + b\n\nadd(2, 3)\nadd.log[-1]

Output

args=(2, 3), kwargs={}

After calling add(2, 3) the decorator stores a string representing the args and kwargs in add.log.

Input format

A decorated function is called within a single expression (the test harness uses eval on expressions).

Output format

Return value of the expression. When checking logs, return the most recent log entry (a string).

Constraints

Do not modify the decorated function's behavior other than adding logging. Use functools.wraps to preserve metadata. The .log attribute must be a list and persist across calls.

Samples

Sample 1

Input

add(1, 2)

Output

3

The decorated add returns the sum, and its log also receives an entry for the call.