Re-executing the code object from a class 'declaration'

Alex Martelli aleaxit at yahoo.com
Wed Oct 6 15:28:40 EDT 2004


Carlos Ribeiro <carribeiro at gmail.com> wrote:
   ...
> > 1. You need to build an f = new.function(klass.my_code, globals()) in
> >    your classmethod that now erroneously does the exec above quoted (you
> >    could in fact do this in the metaclass, save the new function rather
> >    than the code object -- get the right globals via inspect).
> 
> That's the part that I was missing. It looks less 'hackish' than I had
> expect. I was really afraid that I would need to manage bytecode-level
> hacks myself. I am not as concerned about getting the right globals,
> though -- it's good enough if I'm able to supply whatever globals I
> need upon calling, I think (unless I'm _really_ missing something).

I don't think you're missing anything -- just DO consider that if you
pass your own globals they'll be used to solve every name that's not
local to the class body, e.g. a '__metaclass__ = metaname' assignment in
classbody (of course, you can finesse this by calling the metaclass
explicitly anyway;-).


> > 2. you need to obtain the needed dict, that's just  d = f()  in your
> >    method
> 
> There is still a question, but I think I already know the anwswer :-)
> If the class *has* a base class, it has to be passed as a parameter. I
> assume that i can simply call it like this: d=f(bases); or instead,
> that I can fill the argdefs in the new.function call. I'll try it
> later.

Nope, f doesn't get the bases AT ALL; the bases (as a tuple) go in only
when you call the metaclass.


> > 3. you can now call your metaclass with the appropriate bases and name:
> >        klas = self.__class__  # or cls if this is a classmethod;-)
> >        return type(klas)(klas.__name__, klas.__bases__, d)
> > 
> > voila, you're there.  This is all coded to minimize the need to have
> > this method located in a specific class -- as I said I think you
> > probably want to have this stuff in the metaclass (if you have a
> > metaclass at all), but, whatever.
> 
> Tehre are two reasons to do it in a metaclass: first, I tested it and
> it works (of sorts), while for some reason it wont work for a
> non-metaclasses enabled class. Also, because in this scenario there
> are other things that I already need to check, and a metaclass does it
> nicely.

OK, then, that's where you pass the bases in, not before.

> For now, I think I'll just be using the class-inside-a-def idiom. But

If it can give you all you need, that may be best.

> I'm still working around some design issues, and if the templating
> mechanism gets in the final production code (it's only one of a few
> competing designs), I'll surely try it again.

OK, keep us informed of developments, then!


Alex



More information about the Python-list mailing list