python - How to use these two class decorators together with functools.update_wrapper? -


i reading decorators , tried mix these 2 examples , make them class decorators instead of regular functions. first 1 lets run function once per argument , second 1 counts how many times you've run function. both work fine separated when try decorate simple function both @ same time fails... or doesn't fail prints unexpected wrong result. did reading , found functools module can i'm not sure how.

from functools import update_wrapper  class memoize:     def __init__(self, func):         self.func = func         self.memo = dict()         update_wrapper(self, func)      def __call__(self, *args):         if args not in self.memo:             self.memo[args] = self.func(args)         else:             print("cls decorator. have printed before")         return self.memo[args]   class callcounter:     def __init__(self, func):         self.func = func         self.calls = 0         self.__name__ = func.__name__         update_wrapper(self, func)      def __call__(self, *args, **kwargs):         self.calls += 1         return self.func(*args, **kwargs)   @memoize @callcounter def doubleprint(x):     elem in x:         print(elem + " " + elem)   doubleprint('hello') doubleprint('hello') doubleprint('hello') doubleprint('hello') doubleprint('bye')  print(doubleprint.calls)  doubleprint('hello')  doubleprint('hello') doubleprint('hello') doubleprint('hello') doubleprint('bye')  print(doubleprint.calls) 

by default update_wrapper updates __dict__ wrapped class. func in memoize being overwritten func in callcounter means memoize directly calling doubleprint() function , never calling callcounter.

class memoize:     def __init__(self, func):         self.func = func         print(type(self.func))  # <class '__main__.callcounter'>         self.memo = dict()         update_wrapper(self, func)         print(type(self.func))  # <class 'function'> 

you can fix doing:

        update_wrapper(self, func, updated=[]) 

which not copy __dict__ callcounter memoize instance still copy __name__, __doc__, etc.

to access callcounter class would:

print(doubleprint.__wrapped__.calls) 

but need fix above or print 0 (because never called).


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -