File: LP6E/Chapter40/decorators.py
import time
def tracer(func): # Use function, not class with __call__
calls = 0 # Else self is decorator instance only
def onCall(*args, **kwargs):
nonlocal calls
calls += 1
print(f'call {calls} to {func.__name__}')
return func(*args, **kwargs)
return onCall
def timer(label='', trace=True): # On decorator args: retain args
def onDecorator(func): # On @: retain decorated func
def onCall(*args, **kargs): # On calls: call original
start = time.perf_counter() # State is scopes + func attribute
result = func(*args, **kargs)
elapsed = time.perf_counter() - start
onCall.alltime += elapsed
if trace:
funcname, alltime = func.__name__, onCall.alltime
print(f'{label}{funcname}: {elapsed:.5f}, {alltime:.5f}')
return result
onCall.alltime = 0
return onCall
return onDecorator