Python Modules and Packages 5 — Questions and Answers
Question 1: What is an 'editable install' (`pip install -e .`)?
- An install where the package source directory is linked so code changes take effect immediately without reinstalling (Correct answer)
- An install that allows editing the package's metadata after installation
- An install that places the package in a temporary directory
- An install that skips compiling `.pyc` bytecode files
Correct answer: An install where the package source directory is linked so code changes take effect immediately without reinstalling
Editable installs (development mode) add the source directory to `sys.path` via a `.pth` file so changes to the source are reflected instantly.
Question 2: What is the purpose of `PYTHONPATH` environment variable?
- It adds directories to `sys.path` at interpreter startup (Correct answer)
- It specifies the location of the Python executable
- It sets the default encoding for Python source files
- It controls which version of Python pip uses
Correct answer: It adds directories to `sys.path` at interpreter startup
Directories listed in `PYTHONPATH` (colon-separated on Unix) are prepended to `sys.path` when the interpreter starts.
Question 3: What does `importlib.import_module('os.path')` return?
- The `os.path` module object (Correct answer)
- The string `'os.path'`
- The `os` module object
- A `ModuleSpec` for `os.path`
Correct answer: The `os.path` module object
`importlib.import_module()` performs the import and returns the module object, equivalent to `import os.path; return os.path`.
Question 4: What is the effect of deleting a module from `sys.modules` and then reimporting it?
- The module's source file is re-executed and a fresh module object is created (Correct answer)
- Python raises an ImportError because the module no longer exists
- The old module object is returned from cache
- The module is reloaded in place without re-executing its code
Correct answer: The module's source file is re-executed and a fresh module object is created
Removing a module from `sys.modules` causes the next import to treat it as never loaded, re-executing its code and producing a new module object.
Question 5: Which attribute on a package module object contains the list of paths used to find its submodules?
- __path__ (Correct answer)
- __file__
- __spec__
- __package__
Correct answer: __path__
`__path__` is set on package modules to the list of directories searched for submodules; regular (non-package) modules do not have this attribute.
Question 6: What problem does a circular import cause in Python?
- One module may see an incomplete version of the other because it is still being initialized (Correct answer)
- Python raises an ImportError and refuses to run either module
- The second module is silently skipped and not imported
- Python imports both modules twice, causing duplicate definitions
Correct answer: One module may see an incomplete version of the other because it is still being initialized
During a circular import, the partially initialized module is placed in `sys.modules`, so the second module may access attributes that haven't been defined yet.
Question 7: What is the correct way to make a package expose `MyClass` directly (e.g., `from mypackage import MyClass`) when `MyClass` is defined in `mypackage/core.py`?
- Add `from .core import MyClass` inside `mypackage/__init__.py` (Correct answer)
- Rename `core.py` to `MyClass.py`
- Add `MyClass` to `sys.modules['mypackage']`
- Create a `MyClass.py` file at the package root with a `from .core import MyClass` line
Correct answer: Add `from .core import MyClass` inside `mypackage/__init__.py`
Importing `MyClass` in `__init__.py` with `from .core import MyClass` makes it available directly on the package namespace.
What is an 'editable install' (`pip install -e .`)?