decorators and multimethods
Howard Stearns
howard.stearns at charter.net
Sat Aug 7 09:12:21 EDT 2004
Hey, that's pretty nice. I'll have to get some coffee and study this. What
do I read about? I can't find anything about @ or 'decorator' in the 2.3
documentation. What should I be looking for?
Michele Simionato wrote:
> 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