Best Practices and Standardization
This domain is policy, not puzzles: PEP 8 layout and naming, PEP 257 docstrings, the logging hierarchy, unittest structure, type hints and packaging. Questions usually ask which line violates the standard or what a logger actually emits, so precision about constants such as the 79-character limit is what earns marks.
PEP 8 essentials
- Four spaces per indent level, 79-character lines, two blank lines around top-level definitions and one between methods.
snake_casefor functions and variables,CapWordsfor classes,UPPER_CASEfor module constants, a leading underscore for internal names.- One import per line, grouped standard library → third-party → local; no space around
=in keyword arguments:f(a=1).
PEP 257 docstrings
- The docstring is the first statement of the module, function or class; anything before it turns it into a plain string expression.
- Triple double quotes, a one-line summary ending with a period, a blank line, then detail; it becomes
__doc__.
Logging and testing
- Levels ascend DEBUG(10) → INFO(20) → WARNING(30) → ERROR(40) → CRITICAL(50); the root logger defaults to WARNING, so
info()vanishes unlessbasicConfig(level=logging.INFO)runs. - Prefer
logging.getLogger(__name__)and lazy formatting:log.info('x %s', v), not an f-string. unittest.TestCasemethods must start withtestto be discovered;setUp/tearDownrun around each test;assertRaisesworks as a context manager.
Worked example
"""Invoice helpers."""
import logging
log = logging.getLogger(__name__)
def total(items):
"""Return the sum of item amounts."""
log.info('summing %d items', len(items))
return sum(items)
Reasoning: importing this module prints nothing, because the root level is WARNING and info sits below it; adding logging.basicConfig(level=logging.INFO) before the call makes the line appear. The docstring is the first statement, so total.__doc__ is populated.
Traps
- Mutable defaults (
def f(x, acc=[])) persist between calls; useNoneand build inside. - Naming a module after a standard-library module (
logging.py,json.py) shadows it on import, and a test class not inheritingTestCaseis never run.