Differences between revisions 6 and 11 (spanning 5 versions)
Revision 6 as of 2004-08-15 08:27:54
Size: 1927
Editor: proxy1
Comment:
Revision 11 as of 2004-08-18 18:29:18
Size: 3271
Editor: cache-gtc-ab07
Comment:
Deletions are marked like this. Additions are marked like this.
Line 46: Line 46:
(Other hooks could be similarly added. Exceptions are left out for simplicity (Other hooks could be similarly added. Docstrings and exceptions are left out for simplicity
Line 56: Line 56:
    """ Decorator which help to control what aspects to debug.
    Aspects are provided as list of arguments. It DOESN'T
    
slowdown functions which aren't supposed to be debugged.
    """ Decorator which helps to control what aspects of a program to debug
    on per-function basis
. Aspects are provided as list of arguments.
    It DOESN'T slowdown functions which aren't supposed to be debugged.
Line 70: Line 70:
            newf.__doc__ = f.__doc__
Line 85: Line 86:

== Easy adding methods to a class instance ==

Credits to John Roth.

{{{
#!python
class Foo:
    def __init__(self):
        self.x = 42

foo = Foo()

def addto(instance):
    def decorator(f):
        import new
        f = new.instancemethod(f, instance, instance.__class__)
        setattr(instance, f.func_name, f)
        return f
    return decorator

@addto(foo)
def print_x(self):
    print self.x

# foo.print_x() would print "42"
}}}

== Counting function calls ==

{{{
#!python
class countcalls(object):
   "Decorator that keeps track of the number of times a function is called."
   
   __instances = {}
   
   def __init__(self, f):
      self.__f = f
      self.__numCalls = 0
      countcalls.__instances[f] = self
      
   def __call__(self, *args, **kwargs):
      self.__numCalls += 1
      return self.__f(*args, **kwargs)
      
   @staticmethod
   def count(f):
      "Return the number of times the function f was called."
      return countcalls.__instances[f].__numCalls
      
   @staticmethod
   def counts():
      "Return a dict of {function: # of calls} for all registered functions."
      return dict([(f, countcalls.count(f)) for f in countcalls.__instances])
}}}

This page is meant to be a central repository of decorator code pieces, whether useful or not <wink>. It is NOT a page to discuss decorator syntax!

Feel free to add your suggestions (please use the current decorator syntax @dec)!

Memoize

Here's a memoizing class.

inline:memoize.py

Pseudo-currying

   1 class curried(object):
   2   """
   3   Decorator that returns a function that keeps returning functions
   4   until all arguments are supplied; then the original function is
   5   evaluated.
   6   """
   7 
   8   def __init__(self, func, *a):
   9     self.func = func
  10     self.args = a
  11   def __call__(self, *a):
  12     args = self.args + a
  13     if len(args) < self.func.func_code.co_argcount:
  14       return curried(self.func, *args)
  15     else:
  16       return self.func(*args)
  17 
  18 
  19 @curried
  20 def add(a, b):
  21     return a+b
  22 
  23 add1 = add(1)
  24 
  25 print add1(2)

Controllable DIY debug

(Other hooks could be similarly added. Docstrings and exceptions are left out for simplicity of demonstration.)

   1 import sys, sets
   2 
   3 WHAT_TO_DEBUG = sets.Set(['io', 'core'])  # change to what you need
   4 
   5 class deBug:
   6     """ Decorator which helps to control what aspects of a program to debug
   7     on per-function basis. Aspects are provided as list of arguments. 
   8     It DOESN'T slowdown functions which aren't supposed to be debugged.
   9     """
  10     def __init__(self, aspects=None):
  11         self.aspects = sets.Set(aspects)
  12 
  13     def __call__(self, f):
  14         if self.aspects & WHAT_TO_DEBUG:
  15             def newf(*args, **kwds):
  16                 print >> sys.stderr, f.func_name, args, kwds
  17                 f_result = f(*args, **kwds)
  18                 print >> sys.stderr, f.func_name, "returned", f_result
  19                 return f_result
  20             newf.__doc__ = f.__doc__
  21             return newf
  22         else:
  23             return f
  24 
  25 @deBug(['io'])
  26 def prn(x):
  27     print x
  28 
  29 @deBug(['core'])
  30 def mult(x, y):
  31     return x * y
  32 
  33 prn(mult(2,2))

Easy adding methods to a class instance

Credits to John Roth.

   1 class Foo:
   2     def __init__(self):
   3         self.x = 42
   4 
   5 foo = Foo()
   6 
   7 def addto(instance):
   8     def decorator(f):
   9         import new
  10         f = new.instancemethod(f, instance, instance.__class__)
  11         setattr(instance, f.func_name, f)
  12         return f
  13     return decorator
  14 
  15 @addto(foo)
  16 def print_x(self):
  17     print self.x
  18 
  19 # foo.print_x() would print "42"

Counting function calls

   1 class countcalls(object):
   2    "Decorator that keeps track of the number of times a function is called."
   3    
   4    __instances = {}
   5    
   6    def __init__(self, f):
   7       self.__f = f
   8       self.__numCalls = 0
   9       countcalls.__instances[f] = self
  10       
  11    def __call__(self, *args, **kwargs):
  12       self.__numCalls += 1
  13       return self.__f(*args, **kwargs)
  14       
  15    @staticmethod
  16    def count(f):
  17       "Return the number of times the function f was called."
  18       return countcalls.__instances[f].__numCalls
  19       
  20    @staticmethod
  21    def counts():
  22       "Return a dict of {function: # of calls} for all registered functions."
  23       return dict([(f, countcalls.count(f)) for f in countcalls.__instances])

PythonDecoratorLibrary (last edited 2017-07-04 09:44:35 by mjpieters)

Unable to edit the page? See the FrontPage for instructions.