decorating function with logic that intercepts later callswe could simply pass the function and its arguments into manager that dispatches the calldef func(xy)result tracer(func( )nondecorator version def tracer(funcargs)func(*argsspecial call syntax @tracer def func(xy)result func( decorator version rebinds namefunc tracer(funcnormal call syntax manager function approaches like this place the burden of using special syntax on callsinstead of expecting decoration syntax at function and class definitionsbut also allow you to selectively apply augmentation on call-by-call basis why decorators(revisitedso why did just show you ways to not use decorators to implement singletonsas mentioned at the start of this decorators present us with tradeoffs although syntax matterswe all too often forget to ask the "whyquestions when confronted with new tools now that we've seen how decorators actually worklet' step back for minute to glimpse the big picture here before moving on to more code like most language featuresdecorators have both pros and cons for examplein the negatives columndecorators may suffer from three potential drawbackswhich can vary per decorator typetype changes as we've seenwhen wrappers are inserteda decorated function or class does not retain its original type--it is rebound to wrapper (proxyobjectwhich might matter in programs that use object names or test object types in the singleton exampleboth the decorator and manager function approaches retain the original class type for instancesin the tracer codeneither approach doesbecause wrappers are required of courseyou should avoid type checks in polymorphic language like python anyhowbut there are exceptions to most rules extra calls wrapping layer added by decoration incurs the additional performance cost of an extra call each time the decorated object is invoked--calls are relatively timeexpensive operationsso decoration wrappers can make program slower in the tracer codeboth approaches require each attribute to be routed through wrapper layerthe singleton example avoids extra calls by retaining the original class type all or nothing because decorators augment function or classthey generally apply to every later call to the decorated object that ensures uniform deploymentbut can also be decorators