them from the module and code the decoration syntax before each method we wish to trace or timefrom decotools import tracer class person@tracer def __init__(selfnamepay)self name name self pay pay @tracer def giveraise(selfpercent)self pay *( percent@tracer def lastname(self)return self name split()[- bob person('bob smith' sue person('sue jones' print(bob namesue namesue giveraise print(' fsue payprint(bob lastname()sue lastname()giveraise tracer(giverraiseoncall remembers giveraise lastname tracer(lastnameruns oncall(sue runs oncall(bob)remembers lastname when this code is runwe get the following output--calls to decorated methods are routed to logic that intercepts and then delegates the callbecause the original method names have been bound to the decoratorc:\codepy - decoall-manual py call to __init__ call to __init__ bob smith sue jones call to giveraise call to lastname call to lastname smith jones tracing with metaclasses and decorators the manual decoration scheme of the prior section worksbut it requires us to add decoration syntax before each method we wish to trace and to later remove that syntax when we no longer desire tracing if we want to trace every method of classthis can become tedious in larger programs in more dynamic contexts where augmentations depend upon runtime parametersit may not be possible at all it would be better if we could somehow apply the tracer decorator to all of class' methods automatically with metaclasseswe can do exactly that--because they are run when class is constructedthey are natural place to add decoration wrappers to class' methods by exampleapplying decorators to methods