Metaclasses vs. standard Python reflection?

Alex Martelli aleax at aleax.it
Fri May 2 03:02:09 EDT 2003


Jeremy Fincher wrote:

> I've been looking for examples of metaclasses I can use for a talk I'm
> going to be giving next week, but I've been having trouble finding
> examples that solve problems that wouldn't just as easily be via
> Python's uber-reflective __getattr__/__setattr__ and inheritance.
> Does anyone have a good example of a problem that's solved more
> "beautifully" with metaclasses than with Python's standard reflection
> facilities?

If you want to affect the behavior of the class object itself (rather
than the behavior of its instances) you _have_ to do it with a custom
metaclass -- __getattr__/__setattr__ are just not an option here.

http://mail.python.org/pipermail/python-list/2002-July/112007.html
shows metaMetaBunch, one way to do lightweight, effective structs
in Python.  The goal is letting the user code classes such as:

class Point(MetaBunch):
    """ A point has x and y coordinates, defaulting to 0.0, and a color,
        defaulting to 'gray' -- and nothing more, except what Python and
        the metaclass conspire to add, such as __init__ and __repr__
    """
    x = 0.0
    y = 0.0
    color = 'gray'

# example uses of class Point
q = Point()
print q
# must display "Point()"

p = Point(x=1.2, y=3.4)
print p
# must display "Point(x=1.2, y=3.4)" or something similar

In the post, MetaBunch's body is just "__metaclass__=metaMetaBunch",

The metaclass's __new__ builds and injects suitable __init__ and
__repr__ as well as __slots__ at the time the class statement
executes, ensuring minimal overhead in both memory and execution
time.  Here, you _can_ do it with MetaBunch being a classic class
with tricky __getattr__, __setattr__, __init__ and __repr__ -- but,
compare the complication level of the two solutions, the overhead
of the "fully interpretive" solution that's the only one you can
get without custom metaclasses, and the scarce level of control (the
inheritance-based solution is hosed if the user mistakenly overrides
any special method without delicacy and care -- the metaclass can
diagnose such mistakes, warn about them, AND overcome them too).


There have been many significant custom-metaclasses posted in this
group (and google advanced groups search lets you search for them
quite easily).  Metaclasses offer more control (require less
cooperation from the user of the framework and let errors be
diagnosed more easily), better performance (you pay the price
at class-creation time rather than on each and every operation),
AND more functionality (control operations on the class itself).

Of course, getattr/setattr trickery is still there for those rarer
cases when you need extreme dynamism rather than being able to
handle all issues at class-creation time, and/or via property and
other custom descriptors.  But, as one gradually learns, the custom
metaclass solution is often seen as simpler and more immediate as
well as faster, even when an alternative exists at all.


Alex





More information about the Python-list mailing list