Siegfried Gonzi <si*************@kfunigraz.ac.at> wrote in message news:<40***************@kfunigraz.ac.at>...
I am not an expert in CLOS programming. But what are the disadvantages of not having a meta-object protocol? What
is hard to realize then?
This is the kind of questions which would require a book for
even a partial answer :-( In the Lisp world there is "The Art of
the Metaobject Protocol", in the C++ world there is "Putting Metaclasses
to Work", in the Java world there are various books on AOP (anyway
the MOP is not the same as AOP: the MOP is a general framework which
you can use to implemente Aspect Oriented Programming. Metaclasses and
metaobject protocol are essentially the same thing).
I feel the standard answer you get in this case (the MOP is for the ones
who knows why it is useful, if you don't, forget about it) to be a little
frustrating but it is rather difficult to come up with a better answer.
So, what I will do, is to give you an example of the last case where I
used Python metaclasses in a real life application. You will deduce for
yourself if you are missing something useful or not.
My use case was hacking PloneTestCase, the Plone testing framework to
avoid startup times. What I did was to implement a command line
interpreter to execute my tests, reload modules, and similar things.
Python has a beatiful facility for writing command line interpreters,
the "cmd" module in the standard library. You just derive the
cmd.Cmd class and write your commands as methods starting with "do_":
do_this(self, arg), do_that(self, arg)
I had only few commands, it was useful for me to have one-letter aliases:
this means to generate an alias for each method starting with "do_".
You can do that with a function applied to the class, without the MOP.
However, if I subclass later my custom command class, I would like to maintain
the automatic alias feature (this feature has only meaning if I have
less than 26+26 commands of course, otherwise there will be conflicts
so it is not a scalable solution, but this was a quick & dirty hack,
not a masterpiece of software). In order to preserve the feature under
inheritance, you need a metaclass. Here is the solution:
# cmd_with_aliases.py
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
__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
Cmd().cmdloop()
Here is the usage:
~/md/python/Various $ python cmd_with_aliases.py
Hello, World!!
(Cmd) help
Documented commands (type help <topic>):
========================================
g greetings h help q quit
(Cmd) h
Documented commands (type help <topic>):
========================================
g greetings h help q quit
(Cmd) greetings Michele
Hello, Michele!
(Cmd) q
~/md/python/Various $
As you see g,h and q are aliases for greeting, help and quit.
"help greetings" or "help g" or "h greetings" or "h g" all work:
(Cmd) h g
Display a greeting message.
(Cmd) h greetings
Display a greeting message.
(Cmd) help greetings
Display a greeting message.
For me the metaclass solution was the simplest and easier solution
for this job.
I have written a couple of papers on metaclasses in Python that you may
find easily (look at the Python Wiki for instance) and more justifications
for the MOP are given. I mostly use it for hacks concerning testing and
debugging. If I was a framework builder I would have a better use for
it. If I was writing numerical code I would probably not miss it
(I mean, Fortran is not even OO but works pretty well for numerical
tasks). MOP is good if you are writing code for others to use
(for instance if you are writing a command line interpreter as in
this example). As another example, I used metaclasses and descriptors to
hack Python object model in a prototype based one, as a proof of
concept. You can do any kind of fearful hacks (google this newsgroup
for metaclasses). There is really a *lot* you can do. But in 99.9%
of my real life programming I have no use for the MOP.
So, it is up to you to decide if is something worthy or not to learn.
Michele Simionato