This is not possible, at least not in any kind of clean way which only touches a()
. a()
and b()
could contain arbitrary code, which a()
's decorator would not know about. What if you add d()
to b()
? How would the decorator know whether to include d()
in the timing or not?
You could make a global timer which is started and stopped, and decorate a()
with a @start_timer
decorator, and then decorate c()
with a @stop_timer_and_restart_after
decorator. (Edit: this is the "decorate subfunctions as well" option suggested in the comments; wrote this before those comments were added.)
Working example using decorators to define which functions to time and which not to:
import time
import timeit
class Timer(object):
def __init__(self):
self.time_accumulator = 0
self.initial_time = 0
self.current_time = 0
def start_timing(self):
self.initial_time = timeit.default_timer()
def stop_timing(self):
current_time = timeit.default_timer()
elapsed = current_time - self.initial_time
self.time_accumulator += elapsed
timer = Timer()
def timing_decorator(func):
def wrapper():
global timer
timer.start_timing()
func()
timer.stop_timing()
print(timer.time_accumulator)
return wrapper
def stop_and_restart_timing_decorator(func):
def wrapper():
global timer
timer.stop_timing()
func()
timer.start_timing()
return wrapper
@timing_decorator
def a():
time.sleep(.1)
b()
def b():
print("in b")
time.sleep(.2)
c()
@stop_and_restart_timing_decorator
def c():
time.sleep(.3)
print("in c")
a()
Total time on timer is about .3 seconds, as expected.