🌍 Python Programming · subject
Python Programming Modules, Packages and Error Handling Syllabus
The Modules, Packages and Error Handling syllabus for Python Programming in full: 5 chapters and 20 topics, every one listed below, plus 51 Modules, Packages and Error Handling flashcards with answers.
Modules, Packages and Error Handling syllabus: all 5 chapters
Expand any chapter to see its topics and sub-topics.
-
Modules and Packages
4 topics- Importing Modules
- Creating Your Own Modules
- Packages and __init__.py
- The __name__ == '__main__' Idiom
-
Package Management with pip
3 topics- Installing Third-Party Packages
- Requirements Files
- PyPI and Dependency Management
-
Exception Handling
4 topics- try, except, else and finally
- Exception Hierarchy and Built-in Exceptions
- Raising Exceptions
- Custom Exception Classes
-
File Handling and I/O
5 topics- Opening and Closing Files
- Reading and Writing Text Files
- Context Managers and the with Statement
- Working with Binary Files
- File System Operations with os and pathlib
-
The Python Standard Library
4 topics- Math and Random Modules
- Date and Time
- Collections Module
- itertools and functools
Python Programming Modules, Packages and Error Handling flashcards — 51 questions with answers
What is a module in Python, and how do you make its contents available in another file?
A module is any file with a .py extension containing Python definitions and statements. You make its contents available using the import statement, e.g. `import math`, which runs the module once and binds its name in the current namespace.
Compare `import module`, `from module import name`, and `from module import *`.
`import module` binds the module object (access via `module.name`). `from module import name` binds a specific attribute directly (access as `name`). `from module import *` binds all public names (those not starting with `_`, or those listed in `__all__`), polluting the namespace and hurting readability.
How do you import a module under a different (alias) name, and why is it done?
Use the `as` keyword: `import numpy as np`. It shortens long names, avoids naming conflicts, and follows community conventions (e.g. `import pandas as pd`).
When you run `import my_module`, how does Python find the file, and what object results?
Python searches the directories listed in `sys.path` (script dir, PYTHONPATH entries, and installation-dependent defaults). On success it executes the file once and creates a module object bound to `my_module` in the local namespace.
What is `sys.path` and what does it control?
`sys.path` is a list of strings giving the directories Python searches for modules to import. It is initialized from the script's directory (or current dir), the PYTHONPATH environment variable, and installation defaults. You can append to it at runtime to add search locations.
What does `__all__` control in a module?
`__all__` is a list of strings naming the public attributes exported when a client does `from module import *`. If undefined, `*` imports all names not beginning with an underscore.
When you create your own module, how do you prevent its top-level test/demo code from running on import?
Guard the code with `if __name__ == '__main__':`. Code inside this block runs only when the file is executed directly as a script, not when it is imported.
What is the value of the `__name__` variable when a module is (a) imported versus (b) run directly?
When imported, `__name__` equals the module's name (e.g. `'my_module'`). When the file is run directly as the main program, `__name__` equals the string `'__main__'`.
Explain the purpose of the `if __name__ == '__main__':` idiom.
It lets a file serve dual roles: as an importable module (whose functions/classes are reusable) and as a standalone script. Code under the guard executes only during direct execution, providing an entry point without side effects on import.
What is a package in Python, and how has it traditionally been distinguished from an ordinary directory?
A package is a directory that groups related modules into a namespace. Traditionally a directory became a (regular) package by containing an `__init__.py` file, which Python runs when the package is first imported.
What is the role of `__init__.py` in a package?
It marks a directory as a regular package and runs on first import. It can be empty, or it can initialize the package, define `__all__`, or import selected submodule names to expose them at the package level (e.g. `from .core import main`).
What is a namespace package, and how does it differ from a regular package?
A namespace package (PEP 420, Python 3.3+) is a package that has NO `__init__.py` and can be split across multiple directories/`sys.path` entries. A regular package has an `__init__.py` and lives in a single directory tree.
In a package, what is the difference between an absolute import and a relative import?
An absolute import gives the full path from the top-level package, e.g. `from mypkg.utils import helper`. A relative import uses leading dots to reference the current package: `from . import sibling` (same package) or `from .. import cousin` (parent package).
How do you install a third-party package from PyPI, and what tool is standard?
Use pip, the standard package installer: `pip install package_name`. It downloads from the Python Package Index (PyPI) and installs the package plus its dependencies.
What is PyPI?
PyPI (the Python Package Index) is the official public repository of third-party Python packages, hosted at pypi.org, from which pip downloads and installs packages by default.
What is a requirements file, and what is its conventional name?
A requirements file, conventionally named `requirements.txt`, lists a project's dependencies (one per line, optionally version-pinned) so an environment can be reproduced with `pip install -r requirements.txt`.
How do you generate a requirements file capturing the currently installed packages?
Run `pip freeze > requirements.txt`, which writes every installed package with its exact version in `name==version` format.
In a requirements file, what is the difference between `requests==2.31.0`, `requests>=2.31.0`, and `requests~=2.31.0`?
`==2.31.0` pins exactly that version. `>=2.31.0` allows that version or any newer. `~=2.31.0` (compatible release) allows `>=2.31.0, <2.32.0` — patch-level updates but not a new minor version.
What is a virtual environment and why is it used in dependency management?
A virtual environment is an isolated directory with its own Python interpreter and installed packages, created with `python -m venv env`. It prevents dependency conflicts between projects by keeping each project's packages separate from the system Python.
What is semantic versioning (MAJOR.MINOR.PATCH), and what does each part signal?
MAJOR increments for incompatible (breaking) API changes, MINOR for backward-compatible new features, and PATCH for backward-compatible bug fixes. So version `2.5.1` means major 2, minor 5, patch 1.
Show the other 31 Modules, Packages and Error Handling flashcards
Write the general structure of a full try/except/else/finally statement and state when each clause runs.
`try:` runs the protected code. `except SomeError:` runs only if a matching exception is raised. `else:` runs only if the try block raised no exception. `finally:` always runs (exception or not), used for cleanup.
In a try statement, when does the `else` block execute versus the `except` block?
The `else` block executes only if the `try` block completed with NO exception. An `except` block executes only when a matching exception was raised. They are mutually exclusive for a given run.
What is guaranteed about the `finally` block in a try statement?
The `finally` block always executes, whether or not an exception occurred, and even if the try/except/else contains a `return`, `break`, or `continue`, or re-raises. It is used for cleanup like closing resources.
How do you catch multiple different exception types, and how do you access the exception object?
Use multiple `except` clauses, or a tuple: `except (ValueError, TypeError) as e:`. The `as e` binds the exception instance so you can inspect it (e.g. `str(e)`).
What is the root base class of (almost) all built-in exceptions, and which class should user code normally catch or subclass?
`BaseException` is the ultimate root. Ordinary errors derive from `Exception`, which is the class user code should catch and from which custom exceptions should inherit. `BaseException` also parents non-error signals like `SystemExit`, `KeyboardInterrupt`, and `GeneratorExit`.
Why should you generally catch `Exception` rather than `BaseException`?
`BaseException` includes `SystemExit`, `KeyboardInterrupt`, and `GeneratorExit`, which are control-flow signals (program exit, Ctrl-C). Catching them would swallow those signals, so catching `Exception` avoids interfering with normal interpreter shutdown and interruption.
Which built-in exception is raised by indexing a list out of range, and which by a missing dictionary key? What common parent do they share?
An out-of-range list index raises `IndexError`; a missing dict key raises `KeyError`. Both inherit from `LookupError`.
Distinguish `ValueError` from `TypeError`.
`TypeError` is raised when an operation is applied to an object of an inappropriate type (e.g. `'a' + 1`). `ValueError` is raised when the type is right but the value is inappropriate (e.g. `int('abc')`).
Which exception does dividing by zero raise, and what is its parent class?
Dividing by zero raises `ZeroDivisionError`, which is a subclass of `ArithmeticError` (itself a subclass of `Exception`).
What is the difference between `raise` with no arguments and `raise SomeError('msg')`?
`raise SomeError('msg')` creates and raises a new exception with that message. A bare `raise` (only valid inside an `except` block) re-raises the exception currently being handled, preserving its original traceback.
How do you raise an exception while explicitly chaining it to an original cause?
Use `raise NewError('...') from original_exception`. This sets the new exception's `__cause__`, producing a traceback that reads 'The above exception was the direct cause of the following exception.'
How do you define a custom exception class, and what should it inherit from?
Define a class that inherits from `Exception` (or a more specific built-in exception), e.g. `class InsufficientFundsError(Exception): pass`. Inheriting from `Exception` makes it catchable by generic handlers and integrates it into the exception hierarchy.
How would you create a base custom exception for a library and specific subclasses under it?
Define one base, e.g. `class AppError(Exception): pass`, then subclass it: `class ConfigError(AppError): pass` and `class NetworkError(AppError): pass`. Clients can catch all library errors with `except AppError` or handle specific ones individually.
What is the `assert` statement, which exception does it raise, and when is it disabled?
`assert condition, message` raises `AssertionError` with the optional message if the condition is false. Assertions are removed when Python runs with the `-O` (optimize) flag, so they must not be used for essential runtime validation.
What are the three arguments to the built-in `open()` that matter most, and what is the default mode?
`open(file, mode, encoding)`. `file` is the path, `mode` controls read/write/append and text/binary, and `encoding` names the text codec (e.g. `'utf-8'`). The default mode is `'r'` (read, text).
List the file mode characters `'r'`, `'w'`, `'a'`, `'x'`, `'b'`, `'t'`, `'+'` and what each means.
`'r'` read; `'w'` write (truncate/create); `'a'` append (create if absent); `'x'` exclusive create (fail if exists); `'b'` binary; `'t'` text (default); `'+'` open for updating (read and write).
Why must every opened file be closed, and what two ways guarantee closing?
Closing flushes buffered writes to disk and releases the OS file handle. You can call `f.close()` explicitly (ideally in a `finally`), or better, use a `with` statement, which closes the file automatically even if an exception occurs.
Contrast `read()`, `readline()`, and `readlines()` on a text file object.
`read()` returns the entire remaining content as one string (or `read(n)` for n characters); `readline()` returns the next single line including its newline; `readlines()` returns a list of all lines. Iterating the file object directly (`for line in f`) reads it line by line, memory-efficiently.
What is the difference between `write()` and `writelines()`, and does either add newlines?
`write(s)` writes a single string and returns the number of characters written. `writelines(list)` writes each string in an iterable. Neither adds newline characters automatically — you must include `\n` yourself.
What is a context manager, and what two special methods must an object implement to be one?
A context manager is an object that defines runtime setup/teardown for a `with` block. It implements `__enter__(self)` (called on entry, its return value is bound by `as`) and `__exit__(self, exc_type, exc_val, exc_tb)` (called on exit for cleanup).
Why is `with open(path) as f:` preferred over a manual open/close?
The `with` statement uses the file's context-manager protocol to guarantee `f.close()` is called when the block exits — normally or via an exception — preventing resource leaks and eliminating the need for an explicit `try/finally`.
How can you turn an ordinary generator function into a context manager without writing `__enter__`/`__exit__`?
Decorate it with `@contextlib.contextmanager` and `yield` once. Code before the `yield` acts as `__enter__` (the yielded value is bound by `as`), and code after the `yield` acts as `__exit__`.
When reading and writing binary files, what type is exchanged, and how does mode differ from text mode?
Binary mode (`'rb'`, `'wb'`) exchanges `bytes` objects rather than `str`, performs no encoding/decoding or newline translation. Text mode (`'r'`, `'w'`) exchanges `str` and applies the given encoding plus universal-newline handling.
Which module and functions serialize Python objects to binary and back, and what is a security caution?
The `pickle` module: `pickle.dump(obj, file)` / `pickle.dumps(obj)` to serialize, and `pickle.load(file)` / `pickle.loads(data)` to deserialize. Caution: never unpickle data from an untrusted source, because it can execute arbitrary code.
Give three common `os`/`os.path` operations for filesystem work.
Examples: `os.getcwd()` (current directory), `os.listdir(path)` (list entries), `os.makedirs(path)` (create dirs), `os.remove(path)` (delete file), `os.rename(a, b)`; and `os.path.join`, `os.path.exists`, `os.path.basename`, `os.path.splitext` for path manipulation.
What advantages does `pathlib.Path` offer over `os.path`, and how do you join paths with it?
`pathlib` provides an object-oriented, cross-platform path API with methods like `.exists()`, `.is_file()`, `.read_text()`, `.glob()`, and `.parent`/`.name`/`.suffix` attributes. Paths are joined with the `/` operator: `Path('data') / 'file.txt'`.
Name four useful functions from the `math` module and what they compute.
`math.sqrt(x)` gives $\sqrt{x}$; `math.factorial(n)` gives $n!$; `math.floor(x)`/`math.ceil(x)` round down/up to integers; `math.log(x, base)` gives the logarithm. Constants include `math.pi` ($\pi$) and `math.e`.
In the `random` module, distinguish `random.random()`, `random.randint(a, b)`, `random.uniform(a, b)`, and `random.choice(seq)`.
`random.random()` returns a float in $[0, 1)$; `random.randint(a, b)` returns an integer in $[a, b]$ (both inclusive); `random.uniform(a, b)` returns a float in $[a, b]$; `random.choice(seq)` returns a random element from a non-empty sequence.
How do you make results from the `random` module reproducible, and what is the difference between `random.shuffle` and `random.sample`?
Call `random.seed(n)` to fix the pseudo-random sequence. `random.shuffle(lst)` reorders a list in place (returns `None`); `random.sample(pop, k)` returns a new list of `k` unique items without modifying the population.
In the `datetime` module, distinguish `date`, `time`, `datetime`, and `timedelta`.
`date` holds year/month/day; `time` holds hour/minute/second/microsecond; `datetime` combines both; `timedelta` represents a duration (difference between two dates or datetimes). Subtracting two `datetime` objects yields a `timedelta`.
Which methods convert between `datetime` objects and strings, and what do their format codes `%Y`, `%m`, `%d`, `%H`, `%M`, `%S` mean?
`dt.strftime(fmt)` formats a datetime to a string; `datetime.strptime(s, fmt)` parses a string to a datetime. Codes: `%Y` 4-digit year, `%m` month, `%d` day, `%H` 24-hour hour, `%M` minute, `%S` second.
Python Programming Modules, Packages and Error Handling FAQ
What is in the Python Programming Modules, Packages and Error Handling syllabus?
Python Programming Modules, Packages and Error Handling is split into 5 chapters: Modules and Packages, Package Management with pip, Exception Handling, File Handling and I/O and The Python Standard Library. Together they contain 20 topics.
How many chapters are in Python Programming Modules, Packages and Error Handling?
5 chapters, containing 20 topics. The largest chapter is File Handling and I/O, with 5 topics.
Are there flashcards for Python Programming Modules, Packages and Error Handling?
Yes — a 51-card Modules, Packages and Error Handling deck, printed in full in the flashcards section of this page and available in the Examius app with spaced repetition. The free plan covers one exam of your choice, including its flashcards; Examius Pro, a one-time purchase, unlocks every other exam and deck.