About Michele Simionato's "classinitializer" decorator

I

imho

Hi all.
I just send this post as a comment to the third part of Michele
Simionato's article about metaprogramming techniques at:

http://www.ibm.com/developerworks/linux/library/l-pymeta3.html?S_TACT=105AGX03&S_CMP=ART


I found extremely useful the classinitializer "trick". I was thinking
over the caveat not to call a class initializer after the _metaclass_
hook (an exception being raised in that case).
Am I wrong if I state there's a plain solution to this ? I modified the
lines involving "type", replacing it with a custom meta type returned by
a call to frame.f_locals.get("__metaclass__", type), in such a way the
creation of the class involves the right metaclas, even if it was
defined just before the initializer function:

def classinitializer(proc):
# basic idea stolen from zope.interface.advice, P.J. Eby
def newproc(*args, **kw):
frame = sys._getframe(1)
if '__module__' in frame.f_locals and not \
'__module__' in frame.f_code.co_varnames: # we are in a class
thetype = frame.f_locals.get("__metaclass__", type)
def makecls(name, bases, dic):
try:
cls = thetype(name, bases, dic)
except TypeError, e:
if "can't have only classic bases" in str(e):
cls = thetype(name, bases + (object,), dic)
else: # other strange errs, e.g. __slots__ conflicts
raise
proc(cls, *args, **kw)
return cls
frame.f_locals["__metaclass__"] = makecls
else:
proc(*args, **kw)
newproc.__name__ = proc.__name__
newproc.__module__ = proc.__module__
newproc.__doc__ = proc.__doc__
newproc.__dict__ = proc.__dict__
return newproc

This makes the trick work even if a metaclass or another
classinitializer was defined first:

@classinitializer
def enhance(cls, **kw):
for k, v in kw.iteritems():
setattr(cls, k, v)

class M(type):
pass

class A:
__metaclass__ = M
enhance(x=100)
enhance(y=200)

<class '__main__.M'>

What do you think about this solution ?

Diego Novella.
 
M

Michele Simionato

Hi all.
I just send this post as a comment to the third part of Michele
Simionato's article about metaprogramming techniques at:

http://www.ibm.com/developerworks/linux/library/l-pymeta3.html?S_TACT...

I found extremely useful the classinitializer "trick".

I never use it. Too clever. I am waiting for class decorators
in Python 2.6.
I was thinking
over the caveat not to call a class initializer after the _metaclass_
hook (an exception being raised in that case).
Am I wrong if I state there's a plain solution to this ?

I think your solution is fine. Still, consider waiting for
class decorators ;)

Michele Simionato
 
I

imho

Michele Simionato ha scritto:
I never use it. Too clever. I am waiting for class decorators
in Python 2.6.

Uhm... I suspected that :)
I think your solution is fine. Still, consider waiting for
class decorators ;)

Michele Simionato

Of course, I stand waiting here :)

Thanks, Diego.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top