S
Stephan Diehl
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')]
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')]