Check your interview readinessStart Tech Assessment

Python Interview Questions

The Python-specific questions that come up - the GIL, generators, mutability, decorators - with sharp answers.

10 min readUpdated Jul 2026By the TopCoding team

Python interviews test whether you actually understand the language or just use it as a scripting tool. The questions below go one layer beneath syntax - into the GIL, the object model, and the quirks that trip up mid-level engineers. Each has the crisp answer an interviewer is listening for.

#1
Most popular language on LeetCode for interview submissions
CPython
Reference implementation - nearly all interview questions assume it
3.10+
Minimum version to know - match/case, better tracebacks, union types

The GIL and concurrency

The Global Interpreter Lock is the single most common "explain Python internals" question at mid-to-senior level. Know exactly what it does and when it matters.

QuestionSharp answer
What is the GIL?A mutex in CPython that allows only one thread to execute Python bytecode at a time. It protects the reference-count-based memory manager from data races.
Does threading give parallelism in Python?Not for CPU-bound work. Two threads cannot run Python bytecode simultaneously on multiple cores. For I/O-bound work (network, disk) threading is effective because threads release the GIL during blocking I/O calls.
How do you achieve CPU parallelism?multiprocessing - each process has its own GIL and its own interpreter. concurrent.futures.ProcessPoolExecutor is the higher-level API. C extensions (NumPy, Cython) can also release the GIL explicitly.
Will the GIL be removed?PEP 703 (CPython 3.13) added an experimental "free-threaded" build that can disable the GIL. It is opt-in and not yet the default. For interviews, assume the GIL exists unless told otherwise.
When is threading still useful despite the GIL?Any I/O-bound or wait-heavy work: HTTP requests, database queries, file reads, sleep. asyncio is usually a better fit for I/O concurrency, but threading works and is simpler when you need true OS threads.
Interview signal
Saying "threads don't work in Python" is wrong and will cost you points. The correct nuance is "threads don't give CPU parallelism - use multiprocessing for that, asyncio or threading for I/O."

Mutability and the default-argument trap

Python's mutability rules underlie a class of subtle bugs that interviewers love to probe.

QuestionSharp answer
Which built-in types are immutable?int, float, bool, str, bytes, tuple, frozenset. Lists, dicts, sets and most user-defined objects are mutable.
What is the default-argument trap?Default argument values are evaluated once at function definition time, not at each call. So def f(lst=[]) shares the same list object across all calls. The fix: use None as the default and create the mutable object inside the body.
Why does x = [] then y = x then y.append(1) change x?Assignment binds a name to an object; it does not copy. x and y point to the same list. To get an independent copy use y = x.copy() or y = list(x) (shallow) or copy.deepcopy(x) (deep).
When does tuple immutability break down?A tuple can contain a mutable object, e.g. t = ([1, 2],). t[0].append(3) mutates the list inside - the tuple's reference stays fixed but the referenced object changes.

Generators and lazy evaluation

Generators are a first-class Python feature and appear frequently in both language and algorithm questions.

QuestionSharp answer
What is a generator?A function that uses yield instead of return. Calling it returns a generator object (an iterator). Values are produced one at a time on demand - execution resumes from the yield point on each next() call.
Generator vs list comprehension - when to use which?Use a generator expression when you only need to iterate once and the sequence could be large (it holds one value in memory at a time). Use a list when you need random access, multiple passes, or a known-length result.
What is yield from?Delegates to a sub-generator. It passes values through in both directions (supports send() and throw()) and propagates StopIteration cleanly. Equivalent to a loop calling next() on the inner generator, but more efficient and correct.
How do generators relate to iterators?Every generator is an iterator (it implements __iter__ and __next__). Not every iterator is a generator - classes can implement the protocol manually. The iterator protocol is duck-typed: any object with __next__ works in a for loop.
Memory
Lazy evaluation saves memory
A generator over a 10 GB log file uses O(1) memory - one line at a time. A list comprehension over the same file would load the whole thing.
Pipeline
Generators compose
Chain generator expressions to build data pipelines: each stage pulls from the previous lazily, so the full pipeline processes one element at a time end-to-end.

Decorators

Decorators are syntactic sugar for higher-order functions. Interviewers often ask both what they do and how to write one correctly.

QuestionSharp answer
What does @decorator do?It is shorthand for f = decorator(f). The decorator is a callable that receives the original function and returns a replacement (usually a wrapper that adds behaviour before/after calling the original).
Why use functools.wraps?Without it the wrapper function masks the original's __name__, __doc__ and other metadata. @functools.wraps(fn) copies those attributes onto the wrapper, so debugging and introspection still see the original name.
How do you write a decorator that accepts arguments?Add an outer layer: a function that takes the arguments and returns the actual decorator. Three levels total - argument receiver -> decorator -> wrapper.
Where are decorators used in the standard library?@property, @classmethod, @staticmethod, @functools.lru_cache, @functools.cache, @dataclasses.dataclass. Also heavily used in frameworks: @app.route in Flask, @pytest.fixture, etc.

Data model and dunder methods

Python's data model lets user-defined classes hook into built-in syntax. Knowing the key dunder methods signals genuine language depth.

DunderWhat it enables
__repr__ / __str__repr() and str() / print(). __repr__ should be unambiguous (ideally eval-able); __str__ is human-readable. If only one is defined, __repr__ is the fallback for both.
__eq__ and __hash__Equality and use as a dict key or set member. If you override __eq__, Python sets __hash__ to None (making the object unhashable) unless you also define __hash__.
__len__ / __getitem__len() and square-bracket indexing. Implementing both makes the class iterable via the fallback integer-index protocol.
__enter__ / __exit__The context-manager protocol - used with the with statement. __exit__ receives exc_type, exc_val, exc_tb and can suppress exceptions by returning True.
__slots__Not a method but a class variable. Replaces the per-instance __dict__ with a fixed set of slots, reducing memory per instance (important for large numbers of small objects).
__call__Makes an instance callable like a function. Used for stateful callables, function objects, and some design patterns.

is vs == and copy semantics

QuestionSharp answer
Difference between is and ==?is tests identity - both names point to the same object in memory (same id()). == tests equality - calls __eq__. Two distinct objects can be equal without being identical.
Why does x = 256; y = 256; x is y return True?CPython caches small integers (-5 to 256) and short interned strings as singletons. This is an implementation detail of CPython, not guaranteed by the language spec - never rely on it in production code.
Shallow copy vs deep copy?A shallow copy (list.copy(), copy.copy()) creates a new container but the elements are still the same objects. A deep copy (copy.deepcopy()) recursively copies all contained objects. Use deep copy when the structure contains nested mutables you need to isolate.
How do you copy a dict?Shallow: d.copy() or dict(d). Deep: copy.deepcopy(d). For a one-level dict of immutables, shallow is sufficient and faster.
Never use is for value comparison
Writing if x is "hello" looks correct but relies on string interning, which is an implementation detail. Always use == for value equality. Reserve is for None, True, False, and intentional singleton checks.

asyncio basics

asyncio is Python's standard concurrency model for I/O-bound work. Interviewers at companies that use Python backends expect you to explain the event loop and coroutines.

QuestionSharp answer
What is a coroutine?A function defined with async def. Calling it returns a coroutine object; it does not run until awaited or scheduled on an event loop. The event loop drives coroutines by calling send() on the underlying generator.
What does await do?Suspends the current coroutine and yields control back to the event loop until the awaitable (another coroutine, a Task, or a Future) completes. The event loop can run other coroutines in the meantime.
asyncio vs threading for I/O?asyncio uses cooperative multitasking on a single thread - lower overhead, no race conditions on shared state. Threading uses OS threads - simpler to retrofit into synchronous code but has locking overhead. asyncio scales to thousands of concurrent connections; threading caps out sooner.
How do you run multiple coroutines concurrently?asyncio.gather(*coroutines) runs them concurrently and collects results. asyncio.create_task() schedules a coroutine as a background Task without waiting. TaskGroup (3.11+) adds structured concurrency with automatic cancellation on failure.
How do you call a blocking function from async code?loop.run_in_executor(None, blocking_fn, *args) or asyncio.to_thread(blocking_fn, *args) (3.9+). This offloads the call to a thread-pool executor so the event loop is not blocked.
Work through these in a mock interview
Reading these answers is not the same as delivering them under pressure. If you want to sharpen your Python explanations with a senior engineer who runs these exact interviews, book a free call and we will map the gaps.

For the algorithmic side of Python interviews, see the LeetCode Patterns guide - it covers the data structures and patterns that appear alongside language questions in coding rounds.

Sources & further reading

  1. 1Python Data Model - language referencedocs.python.org
  2. 2Glossary: iterator, generator, coroutinedocs.python.org
  3. 3asyncio - Asynchronous I/Odocs.python.org
  4. 4PEP 703 - Making the Global Interpreter Lock Optionalpython.org