question about metaclasses

Stephan Diehl stephan.diehl at gmx.net
Mon Jun 30 12:27:58 CEST 2003


I have a question about metaclasses:

How would be the best way to "merge" different metaclasses?
Or, more precisely, what is the best way to merge metaclass functionality?

The idea is basicly the following:
One has several (metaclass) modules that implements an interesting feature.
Lets say, I have a metaclass L, that adds logging capabilities to all method
calls and another one, called P, that creates properties on the fly.

One possibility would be of course to write a new metaclass LP that merges
the previous two.

As far, as I can see (and I might be wrong here) the only intersting place
in a metaclass is its __new__ method where the classdict of the soon to be
created class can be manipulated.

One idea I had, was to wrap the interesting part (the manipulation of
classdict) in a function and create the actual metaclass on the fly (see
example).

Or would it be better, to create some elaborate inheritance scheme with
metaclasses (they are classes after all) ?

Thanks for your input

Stephan

--------------------------------------------------------------------------

def meta1(classname,bases,classdict):
    classdict['__meta1__'] = 'meta1'

    return classdict

def meta2(classname,bases,classdict):
    classdict['__meta2__'] = 'meta2'

    return classdict

def buildmeta(*metalist):
    metalist = list(metalist)
    class metameta(type):
        def __new__(cls,classname,bases,classdict):
            metalist.reverse()
            for func in metalist:
                classdict = func(classname,bases,classdict)
            return type.__new__(cls,classname,bases,classdict)

    return metameta

class c1(object):
    __metaclass__ = buildmeta(meta1,meta2)

class c2(object):
    __metaclass__ = buildmeta(meta2)

if __name__ == '__main__':
    print [x for x,y in c1.__dict__.items() if x.startswith('__meta')]
    print [x for x,y in c2.__dict__.items() if x.startswith('__meta')]





More information about the Python-list mailing list