This question is an extension of a previous question I posted here: link
I use Python 3.6.2. I have a generic class Framework from which my systems inherit.
I use the decorators on_initialize, on_event, and on_finalize to inform the Framework where each method must be executed. The argument precedence of each decorator is used to determine the order of execution for each section (from lower to higher).
# 3 decorators
def on_initialize(precedence=0):
def marker(func):
func._initializer = precedence
return func
return marker
def on_event(precedence=0):
def marker(func):
func._event_handler = precedence
return func
return marker
def on_finalize(precedence=0):
def marker(func):
func._finalizer = precedence
return func
return marker
# Main framework
class Framework:
def __init_subclass__(cls, *args, **kw):
super().__init_subclass__(*args, **kw)
handlers = dict(_initializer=[], _event_handler=[], _finalizer=[])
for name, method in cls.__dict__.items():
for handler_type in handlers:
if hasattr(method, handler_type):
handlers[handler_type].append((getattr(method, handler_type), name))
for handler_type in handlers:
setattr(cls, handler_type,
[handler[1] for handler in sorted(handlers[handler_type])])
def _initialize(self):
for method_name in self._initializer:
getattr(self, method_name)()
def _handle_event(self, event):
for method_name in self._event_handler:
getattr(self, method_name)(event)
def _finalize(self):
for method_name in self._finalizer:
getattr(self, method_name)()
def run(self):
self._initialize()
for event in range(10):
self._handle_event(event)
self._finalize()
class Recorder(Framework):
@on_finalize(precedence=0)
def save_to_db(self):
print('save_to_db')
class TestFramework(Recorder):
@on_initialize(precedence=0)
def get_data(self):
print('get_data')
@on_initialize(precedence=1)
def prepare_data(self):
print('prepare_data')
@on_event(precedence=0)
def process_event(self, event):
print('process_event', event)
@on_finalize(precedence=1)
def generate_report(self):
print('generate_report')
if __name__ == '__main__':
tf = TestFramework()
tf.run()
The results:
> get_data
> prepare_data
> process_event 0
> process_event 1
> process_event 2
> process_event 3
> process_event 4
> process_event 5
> process_event 6
> process_event 7
> process_event 8
> process_event 9
> generate_report
The method save_to_db from Recorder is not executed in TestFramework. I think I'm missing something in __init_subclass__ where I should be iterating through each subclass. Any idea? Many thanks!