My Python project performs a complex set of operations, and it's important to make clear which operations it uses and in what order. Therefore, it has a main
method that reads like an overview of the project, with the implementation of operation
s outside the main
method.:
class Program:
def main(self): <--- This should be easy to read
res1 = self.operation1()
res2 = self.operation2(res1)
if cond(res2):
res3 = self.operation3(res2)
.......
I also need to output many graphs based on the operations' results - both intermediary and final. This is mostly internal, for deubgging purposes. Since the graphs at later stages depend on the results of previous stages, I needed some container to hold the results over the code run. However, adding the output handling to the main
module really cluttered it.
As a solution, I've wrapped the instance methods in the Program
class with decorators, where the decoratos are implemented in an output
module. Here's how it looks:
----- main.py -------
class Program:
@main_wrap
def main(self):
.......
@wrap1
def operation1(self):
.......
return res
----- output.py -------
def main_wrap(main):
def inner(self):
self.res_container = [] # <-- creating instance variable outside __init__
main(self, *args, **kwargs)
output_final_results(self.res_container)
return inner
def wrap1(func1):
def inner(self, *args, **kwargs):
res = func1(self, *args, **kwargs)
self.res_container.append(res)
output_intermediary_results(res)
return inner
This approach feels very hack-y. I'd appreciate if you could comment or suggest a better solution that ensures both readability of the main
method and proper code writing.