Is this a good use of __metaclass__?

Michele Simionato michele.simionato at gmail.com
Tue May 9 04:41:09 EDT 2006


Joel Hedlund wrote:
> It's not that I'm hellbent on using
> metaclasses - I'm just curious how people think they should be used.

There are very few good use cases for metaclasses. *You should use a
metaclass
only when you want the additional metaclass-induced behavior to be
inherited
in the children classes.*

Here is a made up example (it assume you know the cmd.Cmd class in the
standard
library). Suppose you want to use a metaclasses to add aliases to the
"do_*"
methods of a subclass of cmd.Cmd. You can do it in this way:

import cmd

class make_oneletter_aliases_for_commands(type):
    """Typically used in Cmd classes."""
    def __init__(cls, name, bases, dic):
        for name,func in dic.iteritems():
            if name.startswith("do_"):
                firstletter = name[3]
                setattr(cls, "do_" + firstletter, func)

class Cmd(cmd.Cmd, object): # make it a new-style class, so that super
works
    __metaclass__ = make_oneletter_aliases_for_commands
    def preloop(self):
        """Done once at the beginning."""
        cmd.Cmd.preloop(self)
        self.do_greetings("World!")

    def do_greetings(self, arg):
        """Display a greeting message."""
        print "Hello, %s!" % arg

    def do_help(self, arg):
        """Print this help message."""
        super(Cmd, self).do_help(arg)

    def do_quit(self,arg):
        """Exit the command-loop."""
        return 'quit' # anything != None will do

if __name__ == '__main__':
    Cmd().cmdloop()

Here is how you use it:

$ python cmd_with_aliases.py
Hello, World!!
(Cmd) h

Documented commands (type help <topic>):
========================================
g  greetings  h  help  q  quit

(Cmd) g World
Hello, World!
(Cmd) q

The metaclass has generated the methods 'do_h', 'do_g' and 'do_q' as
aliases for 'do_help', 'do_greetings', 'do_quit' respectively. You
could have
done the same without a metaclass, with a function modifying the class.
However every time you subclass Cmd (or a subclass of it), you would
have to invoke
the function again to generate the aliases corresponding to the new
methods in the subclass. The metaclass performs this step
automagically,
simplifying the life of your users.

If you don't care about giving magic abilities to the subclasses of
subclasses
you don't need a metaclass. For real use of metaclasses, see the Zope
framework code. 

            Michele Simionato




More information about the Python-list mailing list