[{"data":1,"prerenderedAt":144},["ShallowReactive",2],{"topic-python-modules":3},{"framework":4,"topic":15,"subtopics":24},{"id":5,"description":6,"extension":7,"icon":8,"meta":9,"name":10,"order":11,"slug":8,"stem":12,"tier":13,"__hash__":14},"frameworks\u002Fframeworks\u002Fpython.yml","Python interview questions across language fundamentals, data structures and common gotchas for backend, data and automation roles.","yml","python",{},"Python",3,"frameworks\u002Fpython",1,"QsijsotyAr-3rnhJDWWZmc7hE6HAhylS5t1dKpigMOA",{"id":16,"description":17,"extension":7,"frameworkSlug":8,"meta":18,"name":19,"order":20,"slug":21,"stem":22,"__hash__":23},"topics\u002Ftopics\u002Fpython-modules.yml","The import system, packages, __main__, and virtual environments — how Python code is organized, shared and run.",{},"Modules, Packages & Environments",8,"modules","topics\u002Fpython-modules","a8_a5opZ2WGRb6hv-AG427fbrffe_nPB8563DcP43W8",[25,70,105],{"id":26,"title":27,"body":28,"description":32,"difficulty":35,"extension":36,"framework":10,"frameworkSlug":8,"meta":37,"navigation":38,"order":13,"path":39,"questions":40,"related":63,"seo":64,"seoDescription":65,"stem":66,"subtopic":67,"topic":19,"topicSlug":21,"updated":68,"__hash__":69},"qa\u002Fpython\u002Fmodules\u002Fimports.md","Imports",{"type":29,"value":30,"toc":31},"minimark",[],{"title":32,"searchDepth":33,"depth":33,"links":34},"",2,[],"medium","md",{},true,"\u002Fpython\u002Fmodules\u002Fimports",[41,46,50,54,58],{"id":42,"difficulty":43,"q":44,"a":45},"module-vs-package","easy","What is the difference between a module and a package?","A **module** is a single `.py` file — a namespace of functions, classes, and\nvariables you can `import`. A **package** is a **directory of modules**; it\ngroups related modules under one dotted namespace (`mypkg.utils`).\n\nHistorically a package needed an `__init__.py` file to be recognized; that file\nruns when the package is first imported and can expose a curated public API.\nSince Python 3.3, a directory without `__init__.py` can still be a **namespace\npackage**, but a regular package with `__init__.py` is the common, explicit choice.\n\n```python\n# file layout\n# mypkg\u002F\n#   __init__.py      \u003C- makes it a regular package\n#   utils.py         \u003C- a module inside the package\n\nimport mypkg.utils          # import a module from a package\nfrom mypkg import utils     # same module, bound as `utils`\n```\n\nWhy it matters: modules are the **unit of code reuse**, packages are the **unit of\norganization** — both are objects at runtime (`module.__file__`, `package.__path__`).\n",{"id":47,"difficulty":35,"q":48,"a":49},"absolute-vs-relative-imports","What is the difference between absolute and relative imports?","An **absolute import** spells out the full path from a top-level package\n(`from mypkg.utils import helper`). A **relative import** uses leading dots to\nnavigate relative to the **current module's package** — one dot for the current\npackage, two for the parent.\n\n```python\n# inside mypkg\u002Fsub\u002Fthing.py\nfrom mypkg.utils import helper   # absolute — explicit, unambiguous\nfrom ..utils import helper       # relative — '..' = mypkg, then .utils\nfrom . import sibling            # relative — same package\n```\n\nRelative imports only work **inside a package** and only when the module is run as\npart of that package — running the file directly with `python thing.py` breaks them\n(`ImportError: attempted relative import with no known parent package`).\n\nRule of thumb: PEP 8 **prefers absolute imports** for clarity; reach for relative\nimports inside large packages to avoid repeating a long package prefix.\n",{"id":51,"difficulty":43,"q":52,"a":53},"name-main","What does `if __name__ == \"__main__\"` do?","Every module has a `__name__` variable. When a file is **run directly**, Python\nsets its `__name__` to the string `\"__main__\"`. When the same file is **imported**,\n`__name__` is set to the **module's name** instead. The guard therefore runs code\n**only when the file is executed as a script**, not when it's imported.\n\n```python\ndef main():\n    print(\"running as a program\")\n\nif __name__ == \"__main__\":   # True only via `python myfile.py`\n    main()                   # skipped when `import myfile`\n```\n\nThis lets a file double as both an importable library and a runnable program: tests\nand other modules can import its functions without triggering the script logic.\n\nRule of thumb: put **executable entry-point code** under the guard so importing the\nmodule stays free of side effects.\n",{"id":55,"difficulty":35,"q":56,"a":57},"sys-path-resolution","How does Python find the module you import?","On `import x`, Python searches a list of **finders** and, for file-based modules,\nwalks **`sys.path`** — a list of directories — in order, using the **first match**.\n`sys.path` is built from the script's directory (or cwd), the `PYTHONPATH`\nenvironment variable, and the installation's standard library \u002F `site-packages`.\n\n```python\nimport sys\nprint(sys.path)        # ['', '\u002Fusr\u002Flib\u002Fpython3.12', '...\u002Fsite-packages', ...]\n# '' (or the script dir) is searched first — local files can SHADOW stdlib!\n\n# a file named random.py in your folder will hide the real `random` module\n```\n\nBuilt-in modules and frozen modules are found before `sys.path` is consulted, which\nis why you can't shadow `sys` itself.\n\nWhy it matters: a local file named like a stdlib module (`queue.py`, `email.py`)\nsilently **shadows** the real one — a classic, confusing import bug.\n",{"id":59,"difficulty":60,"q":61,"a":62},"import-caching-circular","hard","What is `sys.modules` and how does it relate to circular imports?","`sys.modules` is a **cache** mapping module names to already-imported module\nobjects. The **first** import of a module executes its code top to bottom and stores\nthe result there; every later `import` of the same name just returns the cached\nobject — so module code runs **once** per interpreter session.\n\nA **circular import** is when module A imports B while B imports A. Because the\nimporting module is added to `sys.modules` **before** its body finishes running, the\nsecond import gets a **partially-initialized** module — names defined later in the\nfile aren't there yet.\n\n```python\n# a.py\nimport b                 # starts importing b...\ndef helper(): ...\n\n# b.py\nimport a                 # a is in sys.modules but only HALF-defined\nprint(a.helper)          # AttributeError — helper isn't bound yet\n```\n\nFixes: **move the import inside the function** that needs it (deferred until call\ntime), restructure to remove the cycle, or import the module object rather than\nnames from it. Rule of thumb: circular imports usually signal that two modules\nshould share a third.\n",null,{"description":32},"Python interview questions on the import system — modules vs packages, absolute vs relative imports, __main__, sys.path module resolution, import caching, and circular imports.","python\u002Fmodules\u002Fimports","The Import System","2026-06-18","jtJSf_YAtyPZXIz_7UFkHQ6ZwMS6wa_500IBOxpfjag",{"id":71,"title":72,"body":73,"description":32,"difficulty":35,"extension":36,"framework":10,"frameworkSlug":8,"meta":77,"navigation":38,"order":33,"path":78,"questions":79,"related":63,"seo":100,"seoDescription":101,"stem":102,"subtopic":103,"topic":19,"topicSlug":21,"updated":68,"__hash__":104},"qa\u002Fpython\u002Fmodules\u002Fpackages.md","Packages",{"type":29,"value":74,"toc":75},[],{"title":32,"searchDepth":33,"depth":33,"links":76},[],{},"\u002Fpython\u002Fmodules\u002Fpackages",[80,84,88,92,96],{"id":81,"difficulty":43,"q":82,"a":83},"package-vs-module","What is the difference between a module and a package, and what does __init__.py do?","A **module** is a single `.py` file. A **package** is a **directory** of modules\nthat you import as a unit, traditionally marked by an **`__init__.py`** file. That\nfile runs when the package is first imported, so it's where you can set the\npackage's public API or do setup; it's often empty, which is fine.\n\n```python\n# myapp\u002F                 \u003C- package\n#   __init__.py          \u003C- marks it a package, runs on import\n#   db.py                \u003C- module\n#   utils\u002F               \u003C- subpackage\n#       __init__.py\n#       text.py\n\nimport myapp.db                 # import a module from the package\nfrom myapp.utils.text import slug\n```\n\nA common use of `__init__.py` is to **re-export** so callers can write\n`from myapp import db` cleanly. Modules organize code into files; packages organize\nmodules into a namespace tree.\n",{"id":85,"difficulty":35,"q":86,"a":87},"python-m-main","What do `python -m` and __main__.py do?","**`python -m pkg.module`** runs a module **as a script** while still locating it via\nthe import system (so relative imports and the package context work). When you point\n`-m` at a **package**, Python runs that package's **`__main__.py`** — that's how a\npackage becomes executable, like `python -m http.server`.\n\n```bash\npython -m http.server 8000     # runs http.server's __main__.py\npython -m myapp                # runs myapp\u002F__main__.py\npython -m pytest               # run an installed tool as a module\n```\n\n```python\n# myapp\u002F__main__.py\nfrom myapp.cli import main\nmain()\n```\n\nUse `-m` to run installed\u002Fpackaged code by its import name rather than a file path,\nwhich avoids the `sys.path` surprises you get from running a file directly.\n",{"id":89,"difficulty":35,"q":90,"a":91},"dunder-all","What does __all__ control?","`__all__` is a list of names that defines a module's (or package's) **public API for\nwildcard imports** — `from module import *` imports exactly those names. Without it,\n`import *` grabs every name not starting with an underscore.\n\n```python\n# mymath.py\n__all__ = [\"add\", \"PI\"]      # only these are exported by *\n\ndef add(a, b): return a + b\ndef _helper(): ...           # private anyway\nPI = 3.14159\n\n# elsewhere\nfrom mymath import *         # gets add and PI only\n```\n\nIt does **not** prevent explicit imports (`from mymath import _helper` still works)\n— it only curates `*` and documents intent. Define `__all__` to keep `import *`\nclean and to signal what's officially public.\n",{"id":93,"difficulty":60,"q":94,"a":95},"namespace-packages","What is a namespace package?","A **namespace package** (PEP 420) is a package with **no `__init__.py`** whose\ncontents can be **split across multiple directories** on `sys.path`. Python merges\nthose directories into one logical package — useful for plugins where different\ndistributions contribute to a shared top-level namespace.\n\n```python\n# path1\u002Facme\u002Ffoo.py\n# path2\u002Facme\u002Fbar.py     (no __init__.py in either acme\u002F)\n# with both paths on sys.path:\nimport acme.foo\nimport acme.bar          # both resolve under the merged 'acme' namespace\n```\n\nSince Python 3.3, a directory **without** `__init__.py` can still be importable as a\nnamespace package. For an ordinary single-location package you usually still want a\nregular package (with `__init__.py`); reserve namespace packages for splitting a\nnamespace across separately-installed parts.\n",{"id":97,"difficulty":35,"q":98,"a":99},"script-vs-import","What is the difference between running a file and importing it?","When you **run** a file (`python foo.py`), Python sets its `__name__` to\n**`\"__main__\"`**. When you **import** it, `__name__` is the **module's name**. The\n`if __name__ == \"__main__\":` guard uses this so a file can act as both a runnable\nscript and an importable library — the guarded code runs only on direct execution.\n\n```python\n# greet.py\ndef hello(name): return f\"Hi {name}\"\n\nif __name__ == \"__main__\":   # runs only via `python greet.py`\n    print(hello(\"world\"))    # NOT run when `import greet`\n```\n\nWithout the guard, your script's top-level side effects (running, printing, parsing\nargs) would fire **every time the module is imported**. Always put script entry\npoints behind the `__main__` guard.\n",{"description":32},"Python interview questions on packages vs modules, the role of __init__.py, python -m and __main__.py, __all__, namespace packages, and running a script versus importing it.","python\u002Fmodules\u002Fpackages","Packages & __main__","UrCSSzH8UD9IVaDM_gcmPtivyFD05XPsmRvHMSFzpps",{"id":106,"title":107,"body":108,"description":32,"difficulty":43,"extension":36,"framework":10,"frameworkSlug":8,"meta":112,"navigation":38,"order":11,"path":113,"questions":114,"related":63,"seo":139,"seoDescription":140,"stem":141,"subtopic":142,"topic":19,"topicSlug":21,"updated":68,"__hash__":143},"qa\u002Fpython\u002Fmodules\u002Fvirtual-environments.md","Virtual Environments",{"type":29,"value":109,"toc":110},[],{"title":32,"searchDepth":33,"depth":33,"links":111},[],{},"\u002Fpython\u002Fmodules\u002Fvirtual-environments",[115,119,123,127,131,135],{"id":116,"difficulty":43,"q":117,"a":118},"what-is-venv","What is a virtual environment and why does isolation matter?","A **virtual environment** is a self-contained directory with its own Python\ninterpreter and its own `site-packages`, so each project gets an **isolated** set of\ndependencies. Isolation matters because two projects often need **different\nversions** of the same package — without venvs, installing for one breaks the other,\nand installing globally can even break system tools.\n\n```bash\n# Project A needs Django 3, Project B needs Django 5.\n# Separate venvs let both coexist without conflict.\npython -m venv .venv        # creates an isolated environment\n```\n\nA venv keeps dependencies **per project** and out of the global interpreter, making\nbuilds reproducible and avoiding \"works on my machine\" version clashes. Use one for\nevery project.\n",{"id":120,"difficulty":43,"q":121,"a":122},"create-activate","How do you create and activate a virtual environment?","Create one with the standard-library **`venv`** module, then **activate** it so the\nshell uses the venv's `python` and `pip`. The activation command differs by OS;\n**`deactivate`** returns to the global interpreter.\n\n```bash\npython -m venv .venv            # create (folder named .venv)\n\nsource .venv\u002Fbin\u002Factivate       # activate on macOS \u002F Linux\n.venv\\Scripts\\activate          # activate on Windows\n\nwhich python                    # -> ...\u002F.venv\u002Fbin\u002Fpython while active\ndeactivate                      # leave the venv\n```\n\nOnce active, `pip install` puts packages **inside** the venv only. Add `.venv\u002F` to\n`.gitignore` — you commit the dependency list, not the environment itself.\n",{"id":124,"difficulty":43,"q":125,"a":126},"pip-requirements","How do you install packages and what is requirements.txt?","**`pip install`** fetches packages from PyPI into the active environment. A\n**`requirements.txt`** lists a project's dependencies (often with pinned versions)\nso anyone can recreate the same environment with one command.\n\n```bash\npip install requests            # install latest\npip install \"requests==2.31.0\"  # install a specific version\n\npip install -r requirements.txt # install everything listed in the file\n```\n\n```text\n# requirements.txt\nrequests==2.31.0\nrich>=13.0\n```\n\nCommitting `requirements.txt` makes installs **reproducible** across machines and\nCI. Install into an **activated venv**, never globally with `sudo pip`.\n",{"id":128,"difficulty":35,"q":129,"a":130},"pip-freeze","What does pip freeze do?","`pip freeze` prints every installed package with its **exact pinned version** in\n`requirements.txt` format, so you can capture the current environment. Redirect it\nto a file to snapshot dependencies.\n\n```bash\npip freeze                          # list installed pkgs == versions\npip freeze > requirements.txt       # snapshot the current environment\npip list                            # similar, but human-readable table\n```\n\nA caveat: `pip freeze` records **everything installed, including transitive\ndependencies**, which can make the file noisy. Many teams instead hand-curate\ndirect dependencies (or use a lock-file tool) and keep `pip freeze` for capturing a\nknown-good full snapshot.\n",{"id":132,"difficulty":35,"q":133,"a":134},"editable-install","What is an editable install (`pip install -e`)?","An **editable install** links your project into the environment **in place** instead\nof copying it, so edits to the source take effect **immediately** without\nreinstalling. It's the standard way to work on a package you're developing locally.\n\n```bash\npip install -e .                # install the current project, editable\npip install -e \".[dev]\"         # editable + optional 'dev' extras\n```\n\nBecause the install points at your working tree, changing the code updates the\nimported package right away — no rebuild needed. Use `-e` for **your own package\nunder development**, and a normal `pip install` for third-party dependencies.\n",{"id":136,"difficulty":35,"q":137,"a":138},"pyproject-toml","What is pyproject.toml?","`pyproject.toml` is the **modern, standardized** config file (PEP 518\u002F621) for a\nPython project — it declares the **build system**, project **metadata**, and\n**dependencies** in one place, replacing the older `setup.py`\u002F`setup.cfg` split. Most\nmodern tools (build, pip, linters, formatters) read it.\n\n```toml\n[project]\nname = \"myapp\"\nversion = \"0.1.0\"\ndependencies = [\"requests>=2.31\", \"rich\"]\n\n[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n```\n\nWith dependencies declared here, `pip install .` (or `-e .`) reads them directly, so\na separate `requirements.txt` becomes optional. It's the recommended starting point\nfor any new packaged project.\n",{"description":32},"Python interview questions on virtual environments and pip — what a venv is and why isolation matters, creating and activating one, requirements.txt, pip freeze, editable installs, and pyproject.toml.","python\u002Fmodules\u002Fvirtual-environments","Virtual Environments & pip","J9rM7tWYUq73AiW9CqGkW0bpSbKn9qvu5gGCVDpRVAw",1781808675487]