Metaclass with name overloading.

Alex Martelli aleaxit at yahoo.com
Mon Sep 27 12:49:08 EDT 2004


Carlos Ribeiro <carribeiro at gmail.com> wrote:
   ...
> Forgive me, because I've made a big confusion. For some reason, I
> assumed that the __metaclass__ statement had to be the first one on
> the class declaration. I don't know why. Probably because all examples
> that I have seen so far have were done like that, and in a way, it
> made sense to me -- probably because I wanted it to be that.

Ah, I see.  There is no such constraint, nor does Python need to 'peek'
into the class body _at all_ trying to find all the ways in which the
name __metaclass__ could be bound, even if it was the first statement to
do that binding.  E.g.,

class foo:
    class __metaclass__(type): ...

or

class bar:
    from baz import fee as __metaclass__

and a bazillion other possibilities to bind name '__metaclass__' in the
class body.  Python just executes the class body, _then_ checks if
'__metaclass__' is a key in the resulting dictionary -- that's all.  WAY
simpler and more general, this way.

 
> I think that I'm trying to do too many thing at once, with more
> enthusiasm than solid knowledge. I really feel that I'm on the right
> path, but I'm still missing a lot of stuff. I'll try to rest a little,
> think carefully about all the ideas that have popped in my mind over
> the past week, and try to study it a little better *before* trying to
> post again. Real thanks for all the help.

You're welcome!  Sure, metaclasses are tempting when one is trying to
shoehorn not-quite-feasible things into Python.  And I do appreciate
that one really prefers declarative syntax sometimes... but...

In AB Strakt's CAPS framework, we started out with purely-executable
ways to build Business Logic Modules (calls such as 'blm = MakeBlm(...)'
and 'ent = blm.addEntity(...)' etc etc), then we moved to a simple
"interpreter" churning simple data structures (and doing the
executable-ways of BLM creation under the covers), finally designed a
dedicated, purely declarative language (informally known as 'blam'),
with somewhat Pythonesque syntax, to express each BLM (basically the
result of an Entity-Relationship Diagram analysis, plus embedded Python
code for 'trigger'-like actions, and the like) -- so, now, we parse
'blam' modules into AST's, walk the AST's to generate the needed Python
code, etc.

A dedicated declarative "small language" is, I believe, a better idea
than shoehorning a declarative language into Python.  It lets us choose
the best syntax more freely, provide clearer error messages when
something is wrong, process a BLM in alternate ways (e.g. to produce ERD
graphics rather than executable forms), etc.  However, I understand the
charm of the alternative "embedding" idea.

The ability to use something else than a dict for a frame's f_locals, in
any case, _would_ be neat.  Your other ideas about anonymous members
would require more -- executing the 'function' that's built from the
class body's code-object in a special state where expression's results
aren't just thrown away but processed (much like an interactive
interpreter does -- but merging that with function execution is still
somewhat of a challenge...).  For all this sort of ideas, a good grasp
of the relevant Python internals would help -- if you know enough C,
it's mostly not THAT hard, as said internals are mostly quite cleanly
coded (with a few exceptions where speed is paramount, or regarding the
parsing itself, which isn't the most readable parser in the world;-)...

Module dis is your friend -- you can disassemble any piece of code that
interests you to see what bytecode it produces.  You can then dip into
ceval.c to see exactly what happens on this bytecode or that... it's a
really fun process of learning, really!


Alex



More information about the Python-list mailing list