All sample questions / Python

Python Iterators, Generators and Decorators, what does print(ping.calls) print after def counted(func)?

Block 6, Iterators, Generators and Decorators, question 13 of the Python sample

def counted(func):
    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        return func(*args, **kwargs)
    wrapper.calls = 0
    return wrapper

@counted
def ping():
    return 'pong'

ping()
ping()
ping()
print(ping.calls)

What does this print?

  1. A. 0
  2. B. 1
  3. C. 3
  4. D. 4
Show the answer and why each option is right or wrong

Answer, C. 3

A. 0
Assumes the counter attribute never actually gets incremented.
B. 1
Assumes only the first call updates the counter.
C. 3
Correct. Each call to ping increments the counter stored on the wrapper function object, and it was called three times.
D. 4
Counts one extra call that never actually happened.

Each call to ping actually invokes wrapper, which increments an attribute stored directly on the function object before delegating to the real implementation. Because that counter lives on the wrapper itself rather than being reset per call, it accumulates across all three invocations.

The answer above is what the CPython interpreter printed when the snippet was run, not what someone expected it to do.

This question comes from a bank of 600 Python interview questions, all built the same way, sold as one PDF with the full answer key.

Get the 600 Python questions, 9 euros

Or SQL, Python, pandas and NumPy together, 1,636 questions, 19 euros

Or play the free Python sample, twenty questions in the browser, also as a free PDF.

Previous question Next question

Did this save you a lookup? Buy me a coffee on Ko-fi.