roles that may be bit more typical and practical the next section concludes this with one more common use case--applying operations to class' methods automatically at class creation time exampleapplying decorators to methods as we saw in the prior sectionbecause they are both run at the end of class statementmetaclasses and decorators can often be used interchangeablyalbeit with different syntax the choice between the two is arbitrary in many contexts it' also possible to use them in combinationas complementary tools in this sectionwe'll explore an example of just such combination--applying function decorator to all the methods of class tracing with decoration manually in the prior we coded two function decoratorsone that traced and counted all calls made to decorated function and another that timed such calls they took various forms theresome of which were applicable to both functions and methods and some of which were not the following collects both decoratorsfinal forms into module file for reuse and reference herefile decotools pyassorted decorator tools import time def tracer(func)use functionnot class with __call__ calls else self is decorator instance only def oncall(*args**kwargs)nonlocal calls calls + print('call % to % (callsfunc __name__)return func(*args**kwargsreturn oncall def timer(label=''trace=true)on decorator argsretain args def ondecorator(func)on @retain decorated func def oncall(*args**kargs)on callscall original start time clock(state is scopes func attr result func(*args**kargselapsed time clock(start oncall alltime +elapsed if traceformat '% % fvalues (labelfunc __name__elapsedoncall alltimeprint(format valuesreturn result oncall alltime return oncall return ondecorator metaclasses