Thread-safe singleton and multiton pattern decorators.
pip install philiprehberger-singletonThread-safe singleton and multiton pattern decorators.
pip install philiprehberger-singleton
The @singleton decorator ensures only one instance of a class exists:
from philiprehberger_singleton import singleton
@singleton
class Database:
def __init__(self, url: str) -> None:
self.url = url
db1 = Database("postgres://localhost/mydb")
db2 = Database("postgres://localhost/other")
assert db1 is db2 # same instance
assert db1.url == "postgres://localhost/mydb"
Use reset() to discard the cached instance (useful in tests):
Database.reset()
db3 = Database("postgres://localhost/new")
assert db3.url == "postgres://localhost/new"
instance()instance() returns the cached singleton without constructing one. Useful when callers should not be able to create the singleton, only access it.
Database("postgres://localhost/mydb")
db = Database.instance() # → existing instance
Database.reset()
Database.instance() # raises RuntimeError
The @multiton(key=...) decorator maintains one instance per unique key value:
from philiprehberger_singleton import multiton
@multiton(key="name")
class Connection:
def __init__(self, name: str, timeout: int = 30) -> None:
self.name = name
self.timeout = timeout
cache = Connection("cache", timeout=10)
db = Connection("db", timeout=60)
cache2 = Connection("cache")
assert cache is cache2 # same key -> same instance
assert cache is not db # different key -> different instance
Use reset() to discard all cached instances:
Connection.reset()
| Function / Class | Description |
|---|---|
@singleton | Thread-safe singleton decorator. Returns the same instance on every call. |
@multiton(key) | Thread-safe multiton decorator factory. One instance per unique value of the named parameter. |
cls.reset() | Discards cached instance(s), added by both decorators. |
cls.instance() | Returns the cached singleton without constructing one. Raises RuntimeError if not yet constructed. (Singleton only.) |
pip install -e .
python -m pytest tests/ -v
If you find this project useful: