Writing the instance and reset plumbing by hand for every class gets old. The Pythonic move is to capture the pattern once as a class decorator you can apply anywhere.
Implement singleton. It receives a class and returns a callable that, when called, always hands back one shared instance of that class:
The starter already applies singleton to a Database class. Your job is to make the decorator itself work. Each test defines its own decorated class, so they stay independent even though singleton state lives for the whole process.
class Config:
_instance = None
def __init__(self):
self._data = {}
@classmethod
def instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
@classmethod
def reset(cls):
cls._instance = None
def set(self, key, value):
self._data[key] = value
def get(self, key, default=None):
return self._data.get(key, default)
def has(self, key):
return key in self._data
def singleton(cls):
"""Class decorator: make cls hand back one shared instance on every call."""
# TODO: keep a per-class cache, create once on first call, reuse after
pass
@singleton
class Database:
def __init__(self):
self.connections = 0
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Writing the instance and reset plumbing by hand for every class gets old. The Pythonic move is to capture the pattern once as a class decorator you can apply anywhere.
Implement singleton. It receives a class and returns a callable that, when called, always hands back one shared instance of that class:
The starter already applies singleton to a Database class. Your job is to make the decorator itself work. Each test defines its own decorated class, so they stay independent even though singleton state lives for the whole process.
Press Run Tests or ββ© to check your solution.