decorators and multimethods

Michele Simionato michele.simionato at gmail.com
Sat Aug 7 03:40:24 EDT 2004


Decorators can generate endless debate about syntax, but can also
be put to better use ;)

Actually I was waiting for decorators to play a few tricks that were
syntactically too ugly to be even imaginable for Python 2.3.

One trick is to use decorators to implement multimethods. A while ago
Howard Stearns posted here a recipe to implement generic functions
a.k.a multimethods.

I have not studied his recipe, so don't ask me how it works. All I
did was to add an "addmethod" function and save his code in a module
called genericfunctions.

Decorators allowed me to use the following syntax:

# BEGIN generic functions in Python, example
# use code and examples from Howard Stearns

from genericfunctions import Generic_Function, addmethod

foo = Generic_Function()

@addmethod(object, object, object)
def foo(_, x, y, z):
    return 'default'

@addmethod(int, int, int)
def foo(call_next, x, y, z): 
    return 'all ints , ' + call_next(x, y, z)

@addmethod(object, object)
def foo( _, x, y):
    return 'just two'

print foo # the multimethod table as a dictionary
print foo(1, 2, 'three') # => default
print foo(1, 2, 3) # => all ints, default
print foo(1, 'two')  #> just two
print foo('oops') #=> genericfunctions.NoNextMethod error

# END generic functions in Python, example

Howard Stearns' code is posted here
http://groups.google.it/groups?hl=it&lr=&ie=UTF-8&threadm=40C3BC71.5050206%40charter.net&rnum=1&prev=/groups%3Fq%3Dhoward%2Bstearns%2Bgroup:comp.lang.python.*%26hl%3Dit%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.lang.python.*%26selm%3D40C3BC71.5050206%2540charter.net%26rnum%3D1

I just added the following function:

import sys

def addmethod(*types):
     """sys._getframe hack; works when the generic function is defined
     in the globals namespace."""
     caller_globs = sys._getframe(1).f_globals
     def function2generic(f):
          generic = caller_globs[f.func_name]
          generic[types] = f
          return generic
     return function2generic

Decorators did all the rest ;) Just to add an use case I haven't
seen before.

       Michele Simionato



More information about the Python-list mailing list