recognize this as an adaptation of our person class resurrected from the object-oriented tutorial in )class persondef __init__(selfnamepay)self name name self pay pay @tracer def giveraise(selfpercent)self pay *( percentgiveraise tracer(giveraise@tracer def lastname(self)return self name split()[- lastname tracer(lastnamebob person('bob smith' tracer remembers method funcs bob giveraise runs tracer __call__(??? call to giveraise typeerrorgiveraise(missing required positional argument'percentprint(bob lastname()runs tracer __call__(???call to lastname typeerrorlastname(missing required positional argument'selfthe root of the problem here is in the self argument of the tracer class' __call__ method--is it tracer instance or person instancewe really need both as it' codedthe tracer for decorator stateand the person for routing on to the original method reallyself must be the tracer objectto provide access to tracer' state information (its calls and func)this is true whether decorating simple function or method unfortunatelywhen our decorated method name is rebound to class instance object with __call__python passes only the tracer instance to selfit doesn' pass along the person subject in the arguments list at all moreoverbecause the tracer knows nothing about the person instance we are trying to process with method callsthere' no way to create bound method with an instanceand thus no way to correctly dispatch the call this isn' bugbut it' wildly subtle in the endthe prior listing winds up passing too few arguments to the decorated methodand results in an error add line to the decorator' __call__ to print all its arguments to verify this--as you can seeself is the tracer instanceand the person instance is entirely absentbob giveraise ( ,{call to giveraise traceback (most recent call last)file ""line in file ""line in __call__ typeerrorgiveraise(missing required positional argument'percent decorators