metaclasses vs. inheritance

David Mertz, Ph.D. mertz at gnosis.cx
Fri Jun 28 14:29:09 EDT 2002


|Can someone give an example of a problem that is solved with metaclasses,
|which would be difficult or impossible to solve with inheritance?
|I (very barely) understand metaclasses, but to me it just seems like
|inheritance, where the classes who get the benefit of the meta-class get the
|metaclass' features.

Well...  I am at the "barely" level also.  But my Gnosis_Utils package
contains a moderately useful example of a metaclass.

By way of background, gnosis.xml.pickle pickles Python objects to XML.
There are several ways to use it, but one is:

    # By inheritence
    from gnosis.xml.pickle import XML_Pickler
    class MyClass(XML_Pickler):
    # create some behavior and attributes for MyClass...
    o1 = MyClass()
    # o1 knows how to dump itself
    xml_str = o1.dumps()

Good enough.  But every class that wants to know how to serialize itself
needs to inherit from XML_Pickler.  Here's an alternate approach:

    """Perform black magic of unearthly and ungodly sorts

    Quick Example 1:

        Python 2.2 (#0, Dec 24 2001, 18:42:48) [EMX GCC 2.8.1] on os2emx
        Type "help", "copyright", "credits" or "license" for more information.
        >>> import gnosis.magic
        >>> __metaclass__ = gnosis.magic.MetaPickler
        >>> class Boring:
        ...     def __init__(self):
        ...         self.this = 'that'
        ...         self.spam = 'eggs'
        ...     def print_spam(self):
        ...         print self.spam
        ...
        >>> boring = Boring()
        >>> boring.print_spam()
        eggs
        >>> print boring.dumps()
        <?xml version="1.0"?>
        <!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
        <PyObject module="__main__" class="Boring" id="1276364">
        <attr name="this" type="string" value="that" />
        <attr name="spam" type="string" value="eggs" />
        </PyObject>

    """
    from gnosis.xml.pickle import dumps
    class MetaPickler(type):
        def __init__(cls, name, bases, dict):
            super(MetaPickler, cls).__init__(name, bases, dict)
            setattr(cls, 'dumps', dumps)

--
mertz@  | The specter of free information is haunting the `Net!  All the
gnosis  | powers of IP- and crypto-tyranny have entered into an unholy
.cx     | alliance...ideas have nothing to lose but their chains.  Unite
        | against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------






More information about the Python-list mailing list