I did not follow the grok bit.. He's creating a Descriptor within class 'Spam' by doing @Profiled def bar() because Profiled replaces 'bar' with it's instance that contains __get__
which means I have to do s.grok = 20 to trigger it? Which would imply, s.__get__(instance, instance, value) NOT whatever he's done.. ? How is he passing Spam to 'grok'? It should be (self=decorator-instance, Spam- instance-s and value) being passed to __get__ (for those who don't have the book, he's switched to 'grok' instead of 'bar') >>> s = Spam() >>> def grok(self, x): ... pass ... >>> grok.__get__(s, Spam) class Spam: @Profiled def bar(self, x): print(self, x) import types from functools import wraps class Profiled: def __init__(self, func): wraps(func)(self) self.ncalls = 0 def __call__(self, *args, **kwargs): self.ncalls += 1 return self.__wrapped__(*args, **kwargs) def __get__(self, instance, cls): if instance is None: return self else: return types.MethodType(self, instance) -- https://mail.python.org/mailman/listinfo/python-list