Metaclass with name overloading.

Carlos Ribeiro carribeiro at gmail.com
Mon Sep 27 14:55:15 EDT 2004


On Mon, 27 Sep 2004 19:11:14 +0200, Alex Martelli <aleaxit at yahoo.com> wrote:
> 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!-).

The decorator could play it safe, and at the same time, return
something like the original poster expects. Upon decoration the
following would happen:

1) store the newly declared object in the list __overloaded__<$name>.

2) return a new object (to be bound to the <$name>), where
<$name>.__call__ would return __overloaded__<$name>[-1]; and
f.__iter__ would return an iterator for all declaration in the order
they appear.

I did it as follows; it _almost_ works (which really means it's
broken), because there's a catch that I was not able to solve:

------------
import sys, itertools

class OverloadedFunction:
    def __init__(self):
        self.overload_list = []
    def __iter__(self):
        for item in self.overload_list:
            yield item
    def __getitem__(self, index):
        return self.overload_list[index]
    def __call__(self, *args, **kw):
        return self.overload_list[-1](*args, **kw)
    def append(self, f):
        self.overload_list.append(f)

def overloaded(f):
    d = sys._getframe(1).f_locals
    n = '__overloaded__%s' % f.func_name
    #ofl = getattr(d, n, OverloadedFunction())
    if n in d:
        print "achou"
        ofl = d[n]
    else:
        print "não achou"
        ofl = OverloadedFunction()
    print "<",ofl.overload_list,">", d, n
    ofl.append(f)
    d[n] = ofl
    return ofl

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

   def f(self): return 'second f'
   f = overloaded(f)

print blop.__dict__
# there's a catch -- methods were not bound to the instance
# so I need to pass the 'self' parameter manually
b = blop()
print blop.f(b)
print blop.f[0](b)
print blop.f[1](b)


The problem is that the methods were not bound to the instance. Adding
individual names to each method won't work, because it'll not bind the
references stored in the overload_list. I thought about using a
closure or curry type of solution, but that's something that I still
don't understand very well. Any tips?

-- 
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: carribeiro at gmail.com
mail: carribeiro at yahoo.com



More information about the Python-list mailing list