Metaclasses for class mangling after definition.

François Pinard pinard at iro.umontreal.ca
Mon Jul 19 12:08:07 EDT 2004


[Daniele Varrazzo]

> class Group(Entity):
>     # ... class definition ...

> make_entity(Group)

> [...] But adding such line after each Entity definition bothers me.

> I don't know much about metaclasses: could they help me to
> automatically perform such mangling on the classes "at compile time"
> (or at least once in the class lifetime)? Hints about that?

Not at compile time, but at import time.  Do not fear metaclasses, they
are often useful and very convenient, and easier than many people think.
Here, for example, you could do something like:


__metaclass__ = type
# ...

class Entity:
    class __metaclass__(type):
        def __new__(cls, name, bases, dict):
            if not bases:
                 # If no BASES, this is the Entity class itself, so just
                 # do nothing else then creating the base class.
                 return type.__new__(cls, name, bases, dict)

            # OK.  Here, NAME is a string naming your derived class.
            # BASES is usually the 1-tuple (Entity,) and DICT is the
            # dictionary of all things collected by the import process
            # within the class declaration.  You may choose to first
            # mangle DICT all your soul before creating the class.

            # Then, create the class.  Short and sweet!
            entity = type.__new__(cls, name, bases, dict)

            # ENTITY now holds the derived class.  Instead of mangling
            # DICT before creating the class, it is often easier to add
            # or modify class variables and methods, after the fact,
            # using the dot notation.  (You may do both, of course).

            # Do not forget to return your new class.
            return entity

    # Other Entity methods.

# ...

class Group(Entity):

    # Various Group specific methods.

    # ...

    # The metaclass magic is triggered at this import point.


P.S. - In a few applications, I found very convenient being able to
return something else than a class from the metaclass __new__, so
abusing the `class' syntax in Python to define quite different things.
That has been a cheap way for me to recycle Python syntax and power
instead of parsing new small languages for specialised applications.

-- 
François Pinard   http://www.iro.umontreal.ca/~pinard



More information about the Python-list mailing list