attr descriptor( subject( attr roughly runs descriptor __get__(subject attrxsubjectdescriptors may also have __set__ and __del__ access methodsbut we don' need them here more relevant to this topicbecause the descriptor' __get__ method receives both the descriptor class instance and subject class instance when invokedit' well suited to decorating methods when we need both the decorator' state and the original class instance for dispatching calls consider the following alternative tracing decoratorwhich also happens to be descriptor when used for class-level methodclass tracer(object) decorator+descriptor def __init__(selffunc)on decorator self calls save func for later call self func func def __call__(self*args**kwargs)on call to original func self calls + print('call % to % (self callsself func __name__)return self func(*args**kwargsdef __get__(selfinstanceowner)on method attribute fetch return wrapper(selfinstanceclass wrapperdef __init__(selfdescsubj)save both instances self desc desc route calls back to deco/desc self subj subj def __call__(self*args**kwargs)return self desc(self subj*args**kwargsruns tracer __call__ @tracer def spam(abc)same as prior spam tracer(spamuses __call__ only class person@tracer def giveraise(selfpercent)same as prior giveraise tracer(giveraisemakes giveraise descriptor this works the same as the preceding nested function coding its operation varies by usage contextdecorated functions invoke only its __call__and never invoke its __get__ decorated methods invoke its __get__ first to resolve the method name fetch (on method)the object returned by __get__ retains the subject class instance and is then invoked to complete the call expressionthereby triggering the decorator' __call__ (on ()for examplethe test code' call tocoding function decorators