Programming Practices: Object-Oriented Design and Exception Handling
What this domain tests
Programming practices: object-oriented design and exception handling in data code. The exam checks whether your classes have clear responsibilities and whether failures are handled deliberately rather than swallowed.
Core rules
- A class bundles state and behavior:
__init__sets attributes, and methods operate on them. Prefer composition, such as a loader object used by a pipeline, over deep inheritance. - Encapsulation: keep implementation attributes private by convention with a leading underscore and expose methods.
- Exceptions: catch only what you can handle, name specific types such as
except ValueError:, and useelsefor code that runs when no exception occurred andfinallyfor cleanup. - Raise exceptions with context:
raise ValueError(f'missing column: {col}'). - Use context managers such as
with open(...)andwith sqlite3.connect(...)to guarantee release.
Worked example
A DataLoader class wraps a file path. Its load() method opens the file with with, parses JSON, and raises a custom DataFormatError if the root is not a list. The caller catches DataFormatError, logs the path, and skips that file; it does not catch Exception, so unexpected bugs still surface. Reasoning: the class owns one responsibility, loading; the custom exception communicates a domain-specific failure; and the narrow catch prevents masking programming errors.
Traps that cost marks
except Exception: pass, which hides real bugs.- Catching an exception and continuing with a partially built object.
- Using a mutable default argument such as
def f(items=[])and sharing state across calls. - Forgetting to close files or database connections on the error path.
- Building a deep inheritance hierarchy when a small function or composition would be clearer.