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.