Je pense que pour utiliser le contextlib.contextmanager
(paquet natif) est une bonne idée.
Pour plus de détails, voir ce qui suit.
un exemple simple
from contextlib import contextmanager
class Person:
def __init__(self, name):
self.name = name
def say_something(self, msg):
print(f'{self.name}: {msg}')
@staticmethod
@contextmanager
def enter(name, # <-- members of construct
para_1, options: dict # <-- Other parameter that you wanted.
):
with Person(name) as instance_person:
try:
print(para_1)
print(options)
yield instance_person
finally:
...
def __enter__(self):
print(self.name)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('__exit__')
with Person.enter('Carson', para_1=1, options=dict(key='item_1')) as carson:
carson.say_something('age=28')
print('inside')
print('outside')
sortie
Carson
1
{'key': 'item_1'}
Carson: age=28
inside
__exit__
outside
votre exemple
from typing import Union
from contextlib import contextmanager
def main():
with ClippyRunner.enter(filename="clippytest/Test.xlsx",
param_dict='DATASOURCES[STAGE_RELATIONAL]') as clippy_runner:
clippy_runner.do_something()
class ConnectBase:
def connect(self):
print(f'{type(self).__name__} connect')
def disconnect(self):
print(f'{type(self).__name__} disconnect')
class ExcelConnection(ConnectBase):
def __init__(self, filename):
self.filename = filename
class SQLConnection(ConnectBase):
def __init__(self, param_dict):
self.param_dict = param_dict
class ClippyRunner:
def __init__(self, engine: Union[ExcelConnection], db: Union[SQLConnection]):
self.engine = engine
self.db = db
def do_something(self):
print('do something...')
@staticmethod
@contextmanager
def enter(filename, param_dict):
with ClippyRunner(ExcelConnection(filename),
SQLConnection(param_dict)) as cr:
try:
cr.engine.connect()
cr.db.connect()
yield cr
except:
cr.release() # disconnect
finally:
...
def __enter__(self):
return self
def release(self):
self.engine.disconnect()
self.db.disconnect()
def __exit__(self, exc_type, exc_val, exc_tb):
self.release()
if __name__ == '__main__':
main()
sortie
ExcelConnection connect
SQLConnection connect
do something...
ExcelConnection disconnect
SQLConnection disconnect
À propos de contextmanager
Un gestionnaire de contexte fait (fondamentalement) trois choses :
- Il exécute du code avant un bloc de code.
- Il exécute du code après un bloc de code.
- En option, il supprime les exceptions soulevées dans un bloc de code.