A Python class defines a type whose instances can retain state and expose operations over that state.
Python classes: keep instance state separate from class state
Operation contract
ImportSession allocates a rejected-id list in its constructor. Two instances therefore have different lists. Adding a rejection to one session leaves the other empty. Putting that list on the class would instead provide one shared object unless the code deliberately replaced it for each instance.
Failure and ownership boundary
The class does not validate who may record a rejection or persist session state. A constructor can establish a local invariant, but a shared object used by multiple threads still needs a concurrency policy. Python thread pools: collect results and observe worker failures and Python dataclasses: frozen fields require an immutable value model use that same distinction.
Working program
class ImportSession:
def __init__(self):
self.rejected_ids = []
def reject(self, receipt_id):
self.rejected_ids.append(receipt_id)
first_session = ImportSession()
second_session = ImportSession()
first_session.reject("R41")
print(first_session.rejected_ids)
print(second_session.rejected_ids)Output
['R41']
[]Costs and limits
Each instance retains its own list, which grows with rejected IDs. The fixture imposes no retention limit; a long-running importer needs one.
Common Mistakes
- Do not store per-request mutable lists on the class.
- Object construction does not establish thread safety.
Connected lessons
Python dataclasses: frozen fields require an immutable value model, Python properties: validate mutation at the public attribute boundary, Python thread pools: collect results and observe worker failures.
Apply this boundary
Python descriptors: field validation and attribute precedence, Python super and method resolution: cooperate across mixins, Python Protocol: structural intent without runtime validation.
Follow the related contract
Python staticmethod and classmethod: choose the bound receiver, Python ABC: prevent construction of an incomplete implementation.
