I have a superclass called Insights
with an abstractmethod calculate_insights()
.
Several subclasses inherit, among which the class BrandInsights(Insights)
In the subclasses, the function calculate_insights()
calls upon several other functions. What I want is to have a timing logger for those other functions, without always explicitly adding the logger (as this will greatly reduce readability)
My code now looks like this:
from abc import ABC, abstractmethod
class Insights(ABC):
def __init__(self):
self.bq = BigQueryLayer()
self.db = DatabaseLayer()
@abstractmethod
def calculate_insights(self):
# here should go something to time all functions called in calculate_insights
pass
class BrandInsights(Insights):
def calculate_insights():
self.db.extend_customer_loyalty()
self.db.extend_brand_combiners()
self.db.extend_brand_recency()
...
class StoreInsights(Insights):
def calculate_insights():
self.db.extend_competition_view()
self.db.extend_busiest_hours()
...
How can I make sure a time is logged before and after the execution of every function in calculate_insights()
without explicitly adding it?
Any help would be greatly appreciated!
CodePudding user response:
I don't think its advisable to automagically break apart the implementation of your methods. So I suggest that you break it up yourself which will make it easier to perform things like execution time logging. You can do that with only minor impact on the overall look of the code:
class Insights(ABC):
def timed_execution(self, callbacks):
for callback in callbacks:
start_time = time.time()
callback()
end_time = time.time()
print(f'{callback.__name__} took {end_time-start_time:.3f}s')
class BrandInsights(Insights):
def calculate_insights():
super().timed_execution([
self.db.extend_customer_loyalty,
self.db.extend_brand_combiners,
self.db.extend_brand_recency,
])