@@ -23,7 +23,9 @@ class Extractor(ABC, Logger):
2323 An extractor is used in conjunction with a specific `FileReader`.
2424 """
2525
26- def __init__ (self , extractor_name : str , exclude : list = [None ]):
26+ def __init__ (
27+ self , extractor_name : str , exclude : list = [None ], timed : bool = False
28+ ) -> None :
2729 """Construct Extractor.
2830
2931 Args:
@@ -32,10 +34,12 @@ def __init__(self, extractor_name: str, exclude: list = [None]):
3234 data, and to name tables to which this data is
3335 saved. E.g. "mc_truth".
3436 exclude: List of keys to exclude from the extracted data.
37+ timed: Whether to time the execution of the __call__ method.
3538 """
3639 # Member variable(s)
3740 self ._extractor_name : str = extractor_name
3841 self ._exclude = exclude
42+ self ._timed = timed
3943
4044 # Base class constructor
4145 super ().__init__ (name = __name__ , class_name = self .__class__ .__name__ )
@@ -72,4 +76,24 @@ def name(self) -> str:
7276 def __init_subclass__ (cls ) -> None :
7377 """Initialize subclass and apply the exclude decorator to __call__."""
7478 super ().__init_subclass__ ()
75- cls .__call__ = cls .exclude (cls .__call__ ) # type: ignore
79+ if not cls ._timed :
80+ cls .__call__ = cls .exclude (cls .__call__ ) # type: ignore
81+ else :
82+ import time
83+
84+ cls .__call__ = cls .exclude (cls .__call__ ) # type: ignore
85+ # wrap with time logging
86+ original_call = cls .__call__
87+
88+ def timed_call (
89+ cls : "Extractor" , * args : Any
90+ ) -> Union [dict , pd .DataFrame ]:
91+ start_time = time .time ()
92+ result = original_call (cls , * args )
93+ end_time = time .time ()
94+ cls ._logger .info (
95+ f"Extractor { cls .name } took { end_time - start_time :.4f} seconds."
96+ )
97+ return result
98+
99+ cls .__call__ = timed_call # type: ignore
0 commit comments