← All public quizzes
Start the quiz (as a guest or with an account)
Python — Decorators, closures & async (advanced)
by Jude · 23/05/2026 · 106 views · shares
Higher-order functions, decorators with/without args, closures, async/await, concurrency models. 20 questions.
20
Questions
🇬🇧 English
Language
Hard
Difficulty
Questions in this quiz
-
1. What does a decorator do?
- Adds type hints
- Wraps a function/class to return a (usually new) callable
- Compiles the function to C
- Renames the function at runtime
-
2. Why use
functools.wraps?- Thread safety
- Copies
__name__,__doc__,__wrapped__from the wrapped function - Deep-copies arguments
- Memoizes results
-
3. What is printed?
def make_counter(): n = 0 def inc(): nonlocal n n += 1 return n return inc c = make_counter() print(c(), c(), c())- 1 1 1
- 1 2 3
- 0 1 2
- Error
-
4. Which decorator caches results of a pure function?
@functools.lru_cache@staticmethod@property@dataclass
-
5. What does this print?
import asyncio async def main(): return 42 print(type(main()))- <class 'int'>
- <class 'coroutine'>
- <class 'function'>
- <class 'Future'>
-
6. Which is true about
asyncio?- Runs on multiple OS threads
- Cooperative single-threaded event loop — concurrency comes from
awaitpoints - Bypasses the GIL for CPU-bound code
- Linux-only
-
7. How do you run two coroutines concurrently and wait for both?
await a; await bawait asyncio.gather(a, b)asyncio.run(a); asyncio.run(b)asyncio.sleep(a, b)
-
8. What does this decorator do?
def retry(n): def deco(fn): def wrapper(*a, **k): for _ in range(n): try: return fn(*a, **k) except Exception: pass return None return wrapper return deco- Retries up to
ntimes, swallowing exceptions; returnsNoneon total failure - Calls once and ignores errors
- Times the function
- Caches the result
- Retries up to
-
9. Difference between threads and asyncio tasks for I/O-bound work?
- Threads are always faster
- Asyncio tasks are typically lighter and explicit at
awaitpoints; threads are preemptive and heavier - Same thing
- Threads can't do networking
-
10. Which best represents a class-based decorator?
- Class with
__init__and__call__ - Class with
__enter__/__exit__ - Class with
__iter__ - Class with
__getattr__
- Class with
-
11. What does this print?
def stack(*decos): def apply(fn): for d in reversed(decos): fn = d(fn) return fn return apply def A(fn): def w(*a, **k): print("A"); return fn(*a, **k) return w def B(fn): def w(*a, **k): print("B"); return fn(*a, **k) return w @stack(A, B) def f(): print("f") f()- f
- A B f
- B A f
- A f B
-
12. What does this output?
import asyncio async def slow(): await asyncio.sleep(0) return 1 async def main(): t = asyncio.create_task(slow()) print("scheduled") return await t print(asyncio.run(main()))- 1
- scheduled then 1
- 1 then scheduled
- Error
-
13. What's wrong with mixing
time.sleep(5)inside anasyncfunction?- Nothing
- It blocks the entire event loop, defeating asyncio's purpose; use
await asyncio.sleep(5) - It is faster than asyncio.sleep
- Raises a runtime error
-
14. What does
functools.partial(f, 1, b=2)do?- Calls
f(1, b=2)immediately - Returns a callable with
1andb=2pre-bound - Creates a new function with default
1only - A no-op
- Calls
-
15. Which is true about the GIL in CPython?
- Removed in 3.10
- Allows multiple Python bytecodes to execute simultaneously on multiple threads
- Ensures only one thread executes Python bytecode at a time; doesn't help CPU-bound multi-threading
- Only present on Windows
-
16. What is an
async with?- Syntax error
- Context manager that uses awaitable
__aenter__/__aexit__ - Tries the block asynchronously
- Same as
with
-
17. What does this print?
import asyncio async def first(): await asyncio.sleep(0.01) return "first" async def second(): return "second" async def main(): for c in asyncio.as_completed([first(), second()]): print(await c) asyncio.run(main())- first then second
- second then first
- Always alphabetical
- Both at once
-
18. How do you cancel an asyncio task safely?
task.cancel()and await it, handlingCancelledErrordel tasktask.kill()- Set
task.done = True
-
19. What is the purpose of
contextvars.ContextVar?- Replace global variables for sync code
- Carry per-task contextual state across
awaitboundaries in asyncio - Improve dict lookup speed
- Schedule background tasks
-
20. Which decorator preserves the original signature for help/IDE introspection on the wrapped function?
- Hand-written wrapper without
functools.wraps - Wrapper using
@functools.wraps(fn) - Using
*args, **kwargsalone - Using
lru_cache
- Hand-written wrapper without