Decorators and Closures Flashcards
6 cards from real HACKERRANK practice questions. Tap to flip, then mark Knew It or Still Learning — missed cards come back until you master them.
Read the first 6 Decorators and Closures flashcards as text
What is a closure in Python?
Answer: A function that retains access to variables from its enclosing scope even after that scope has finished executing
A closure is an inner function that captures and remembers variables from its enclosing function's scope. The enclosing scope's variables persist as long as the closure exists, even after the outer function returns.
What does the following code print? python def make_multiplier(n): def multiply(x): return x * n return multiply double = make_multiplier(2) print(double(5))
Answer: 10
make_multiplier(2) returns the inner function multiply with n=2 captured in its closure. Calling double(5) executes multiply(5) with the remembered n=2, returning 5*2=10.
What is the effect of applying a decorator using @syntax? python @my_decorator def greet(): return 'hello'
Answer: It is equivalent to greet = my_decorator(greet)
The @decorator syntax is syntactic sugar. @my_decorator above a function definition is exactly equivalent to writing greet = my_decorator(greet) immediately after the def block.
Why is functools.wraps used inside a decorator?
Answer: To preserve the original function's __name__ and __doc__ on the wrapper function
Without @functools.wraps(func), the wrapper function replaces the original's metadata, making debugging harder. @functools.wraps(func) copies __name__, __doc__, and other attributes from the original function to the wrapper.
What does the nonlocal keyword do in the following code? python def counter(): count = 0 def increment(): nonlocal count count += 1 return count return increment
Answer: Allows increment() to modify the count variable in counter()'s scope
Without nonlocal, count += 1 inside increment() would create a new local variable, causing an UnboundLocalError. nonlocal count tells Python to use the count from the nearest enclosing (non-global) scope — counter()'s frame.
What is the output of the following decorator example? python def shout(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) return result.upper() return wrapper @shout def greet(name): return f'hello {name}' print(greet('world'))
Answer: HELLO WORLD
The shout decorator wraps greet so that its return value is passed through .upper(). greet('world') returns 'hello world', and the wrapper returns 'hello world'.upper() = 'HELLO WORLD'.