Metaclasses vs. standard Python reflection?

Michele Simionato mis6 at pitt.edu
Fri May 2 09:59:18 EDT 2003


Ian Bicking <ianb at colorstudy.com> wrote in message news:<mailman.1051855744.4250.python-list at python.org>...
<snip>
>In fact, I think they are much more complex than they need be.  

I don't think so. I cannot imagine a simpler way of doing all that
metaclasses can do, at the same level of generality. The real problem
is that there is very little documentation about them.

>I'd rather have it implemented something like:
>
>class SQLObject(object):
>
>    def __newclass__(className, bases, vardict):
>        # change vardict, perhaps...
>        cls = object.__newclass__(className, bases, vardict)
>        # do more stuff...
>        return cls
>
>It really does seem to just boil down to effecting the class
>instantiation, and there's no reason there couldn't be an __initclass__
>and __newclass__ methods that were analogs of __init__ and __new__ for
>instances.  You do need change the class *at* instantiation instead of
>after if you want to fiddle with __slots__, and perhaps there's some
>other similar cases (though I can't think of any others).   

But then you would need __getitemclass__, __strclass__, __reprclass__,
 __hashclass__, __getattrclass__, __getattributeclass__,
__setattributeclass__,__iterclass__,__lenclass__, .... etc. etc. etc.

Metaclasses are pretty consistent with Python object model, and IMHO
they are another example of Python *excellent* design.

>Maybe people have other novel uses of metaclasses that couldn't be done
>with a builder (well, couldn't be done as well... I suspect there's not
>actually anything that *couldn't* be done by invoking a builder in some
>way, you can even kind of do __slots__, but it just doesn't look at
>nice).
>
>  Ian

There are things you can do with metaclasses only, such as redefining
__getitem__, __str__, __repr__, etc. at the class level. But you may argue
that this is syntactic sugar. 
I do agree with you that most of the things you can do with metaclasses,
can be done with a smart class factory. The real convenience is in inheritance:
if A is generated by Meta_A, when I derive B from A, B will be
*automatically* generated by Meta_A. On the other hand, if A is generated
by Factory_A, you must generate B by hand using Factory_A: if you simply
derive B from A, you will inherits the methods and attributes of A,
but not the additional bonuses of the factory. It is true that in
most usages this is not so bad; but if you are doing advanced stuff,
the advantage of metaclasses over class factories becomes really sensible.

There are also other conveniences: for instance you can rejuvenate *all*
the old style classes in a module with a single line, __metaclass__=type.

Of course, you can do the same with something like (pseudocode)

   for oldcls in old_classes_in_the_module:
       newclass=CreateNewClass(oldcls.__name__,
                              (oldcls,object),oldcls.__dict__.copy())

but you will admit that this is much uglier.

Cheers,

                                                    Michele

P.S. the OP maybe interested in 
http://www-106.ibm.com/developerworks/library/l-pymeta.html




More information about the Python-list mailing list