D

Python Interview Questions

Concise, interview-ready answers on Python environments, packaging and scripting fundamentals.

Updated 2026-09-03

On this page
What problem does a virtual environment solve?

Without one, every project on a machine shares the same global set of installed packages — two projects needing different versions of the same library can't coexist, and installing a dependency for one project can silently break another. A venv gives each project its own isolated package directory and its own pip/python binaries.

Why is subprocess.run(cmd, shell=True) risky?

With shell=True, the command string is handed to a real shell for interpretation — if any part of it is built from external input (a CLI argument, an API payload, an environment variable), an attacker can inject shell metacharacters to run arbitrary commands. Passing a list of arguments instead never invokes a shell, so there's nothing to inject into.

What's the difference between a list and a tuple?

Both are ordered collections. A list is mutable — items can be added, removed or changed after creation. A tuple is immutable — its contents are fixed once created, which makes it hashable (usable as a dict key or set member) and signals intent that the collection shouldn't change.

What's the difference between args and kwargs (*args, **kwargs)?

*args collects any extra positional arguments into a tuple; **kwargs collects any extra keyword arguments into a dict. They let a function accept a variable, unspecified number of arguments — common in wrapper/decorator functions that need to pass whatever they're given through to another function unchanged.

What is the GIL, and why does it matter for concurrency?

The Global Interpreter Lock ensures only one thread executes Python bytecode at a time in CPython, even on a multi-core machine. That makes threading a poor fit for CPU-bound work (it won't actually parallelize across cores), but threading still helps for I/O-bound work (network calls, disk I/O) since the GIL is released during blocking I/O. For genuine CPU parallelism, use multiple processes (multiprocessing) instead.

What's the difference between == and is?

== compares value equality — do these two objects represent the same value. is compares identity — are these two names literally bound to the same object in memory. Two equal-looking lists are == but not is; comparing against None should always use is None, since None is a singleton and identity is both correct and faster.

What's the difference between a script argument sourced from argparse versus os.environ?

A CLI argument (argparse) is explicit at invocation time and shows up in shell history and process listings — fine for non-sensitive config like --env staging. An environment variable is set in the process's environment rather than the command line, which keeps it out of ps output and shell history — the more common choice for secrets like API keys, though neither is a substitute for a real secrets manager in production.

What does if __name__ == "__main__": do?

__name__ is "__main__" only when a file is run directly, and is the module's actual name when it's imported by something else. This guard lets a file define reusable functions/classes that other code can import without also re-running the file's top-level script logic as a side effect of importing it.

How would you handle a missing required environment variable?

os.environ["KEY"] raises KeyError immediately if it's unset — fail loudly at startup rather than limping along with a None that causes a confusing error much later. Use os.environ.get("KEY", default) only for genuinely optional configuration with a sane default.