Differences between revisions 1 and 10 (spanning 9 versions)
Revision 1 as of 2004-08-10 20:46:05
Size: 247
Editor: dsl-082-082-053-236
Comment:
Revision 10 as of 2004-08-18 18:28:02
Size: 3261
Editor: cache-gtc-ab07
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
It is NOT a page to discuss about decorator syntax! It is NOT a page to discuss decorator syntax!
Line 5: Line 5:

== Memoize ==

Here's a memoizing class.

inline:memoize.py

== Pseudo-currying ==

{{{
#!python
class curried(object):
  """
  Decorator that returns a function that keeps returning functions
  until all arguments are supplied; then the original function is
  evaluated.
  """

  def __init__(self, func, *a):
    self.func = func
    self.args = a
  def __call__(self, *a):
    args = self.args + a
    if len(args) < self.func.func_code.co_argcount:
      return curried(self.func, *args)
    else:
      return self.func(*args)


@curried
def add(a, b):
    return a+b

add1 = add(1)

print add1(2)

}}}

== Controllable DIY debug ==

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

{{{
#!python
import sys, sets

WHAT_TO_DEBUG = sets.Set(['io', 'core']) # change to what you need

class deBug:
    """ 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.
    """
    def __init__(self, aspects=None):
        self.aspects = sets.Set(aspects)

    def __call__(self, f):
        if self.aspects & WHAT_TO_DEBUG:
            def newf(*args, **kwds):
                print >> sys.stderr, f.func_name, args, kwds
                f_result = f(*args, **kwds)
                print >> sys.stderr, f.func_name, "returned", f_result
                return f_result
            newf.__doc__ = f.__doc__
            return newf
        else:
            return f

@deBug(['io'])
def prn(x):
    print x

@deBug(['core'])
def mult(x, y):
    return x * y

prn(mult(2,2))

}}}

== 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 ==

{{{
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

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])

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

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