Menu

Sign in to track your progress and unlock all features.

Theme style

Log in

Full lesson preview

Create a Decorator That Counts Calls

Implement a decorator that tracks how many times a function is called and exposes the count as an attribute.

Python practice8 minDecorators FundamentalsBeginnerLast updated April 15, 2026

Problem statement

Decorators let you wrap and extend function behavior. In this lesson you'll implement a decorator named count_calls that increments a counter every time the decorated function is invoked. The decorator must: - Work with any function signature (accept *args and **kwargs). - Preserve the original function's metadata (name, docstring) using functools.wraps. - Expose a mutable attribute .call_count on the decorated function (starting at 0) that reflects the number of times the function has been called. Your implementation should not change the function's return value. Use the decorator to wrap sample functions and ensure the call counts update correctly even when functions return None.

Task

Write a decorator @count_calls that wraps any function, increments a counter on each call, preserves the wrapped function's metadata with functools.wraps, and exposes the call count as .call_count.

Examples

Basic usage

Input

@count_calls\ndef add(a, b):\n return a + b\n\nadd(1, 2)\nadd(3, 4)\n(add.call_count, add(5,6), add.call_count)

Output

(2, 11, 3)

After two calls add.call_count is 2. Calling add(5,6) returns 11 and increases call_count to 3. The final tuple shows the count before the last call, the return value, and the new count.

Input format

You will implement the decorator function count_calls and use it to decorate functions. Tests call the decorated functions and inspect .call_count.

Output format

Expressions return values (e.g., tuples or strings). The test harness compares str(value) to expected strings.

Constraints

- Use functools.wraps to preserve metadata. - The decorator must attach a .call_count attribute to the returned (decorated) function. It should start at 0. - Do not print; functions should return values normally. - Support any arguments/keyword arguments.

Samples

Sample 1

Input

@count_calls\ndef greet(name):\n return f"Hi {name}"\n\n(greet('Eve'), greet.call_count)

Output

('Hi Eve', 1)

Calling greet once returns the greeting and sets greet.call_count to 1.