Metaclass with name overloading.

Alex Martelli aleaxit at yahoo.com
Mon Sep 27 13:11:14 EDT 2004


Thomas Heller <theller at python.net> wrote:
   ...
> It won't work for ordinary attributes, but for overloading methods you
> should be able to play some tricks with decorators and sys._getframe().

Great idea... love it!!!  To clarify it a bit for people who may not be
as familiar with internals as Mr Heller...: a decorator 'sees' the
method it's decorating "at once", so it doesn't matter if that method's
name later gets trampled upon... as long as the decorator can stash the
original away somewhere, and the frame in which the class body is
executing is just the right 'somewhere'.

A code snippet may be clearer than words...:

import sys, itertools

_ignore_method = object()

def overloaded(f):
    d = sys._getframe(1).f_locals
    n = '__overloaded__%s__%%d' % f.func_name
    for i in itertools.count():
        nx = n % i
        if nx in d: continue
        d[nx] = f
        break
    return _ignore_method

class blop:
    @ overloaded
    def f(self): return 'first f'
    @ overloaded
    def f(self): return 'second f'

print blop.__dict__


so, class blop doesn't really have an 'f' (it does have it in the
__dict__, but it's a dummy '_ignore_method' entry with a suitable custom
metaclass would easily prune!-) but has __overloaded__f__0 and
__overloaded__f__1 methods (which, again, a suitable custom metaclass
could do whatever wonders with!-).

For overload purposes, you might have the decorator actually take as
arguments some _types_ and record them so that the metaclass can arrange
for the dispatching based on actual-argument types...

If you bletch at having to decorate each overloaded version with
'@overloaded', consider C# basically requires that "just BECAUSE",
without even having a good excuse such as "we need to do it that way due
to Python's semantics"...;-)


Alex



More information about the Python-list mailing list