I think I prefer this version:
class Session:
def __init__(self):
self._connection = db.connect(...)
def __enter__(self):
self._connection.__enter__(self)
return self
def __exit__(self, *args):
return self._connection.__exit__(self)
def login(self, name, password):
self._connection.query(...)
with Session() as session:
...
It might need a bit more knowledge about context managers [1], but it feels less magic and more explicit to me – i.e. more pythonic :). But it also contains the assumption that db.connection already returns the connection. If that is not true, a bit more housekeeping is needed: class Session:
def __init__(self):
self._connection_context = db.connect(...)
def __enter__(self):
self._connection = self._connection_context.__enter__(self)
return self
def __exit__(self, *args):
return self._connection_context.__exit__(self)
def login(self, name, password):
self._connection.query(...)
[1] https://docs.python.org/3/library/stdtypes.html#typecontextm...