PEP 318
Andrew Bennetts
andrew-pythonlist at puzzling.org
Wed Mar 24 01:00:57 EST 2004
On Tue, Mar 23, 2004 at 09:04:44PM -0800, Michele Simionato wrote:
> Skip Montanaro <skip at pobox.com> wrote in message news:<mailman.289.1080056808.742.python-list at python.org>...
> >
> > Okay, but can you explain the mechanism or point me to the original post? I
> > can't find it on Google (probably too recent). Multimethod(a,b)() won't
> > know that each call is for __mul__ will it (maybe it will peek at the
> > func_name attribute)? From what you posted, all I saw was multiple
> > definitions of __mul__. Only the last one will be present as a method in
> > the class's definition.
> >
> > Skip
>
> Please take what I posted just as an idea (it is not even my idea!), not as
> an implementation proposal.
> I don't have an implementation, but I am pretty much convinced that it is
> possible and not that hard.
> I am not suggesting that we put multimethods in Python 2.4.
> I am just noticing that the notation could be used to denote
> multimethods too, as Ville Vainio suggested (sorry for the mispelling,
> Ville!).
>
> Just to support your point that the decorator idea is a Pandora box, and
> we can extract anything from it ;)
But the decorator syntax doesn't help with this case at all.
You *could* hack up multimethods today, though, by abusing metaclasses:
class Foo:
...
class __mul__(multimethod):
def Matrix(self, other):
...
def Vector(self, other):
...
The definition of multimethod would be something like this:
class _multimethod(type):
def __new__(cls, name, bases, d):
if d.get('__metaclass__') == _multimethod:
return super(_multimethod, cls).__new__(cls, name, bases, d)
else:
def multi(self, *args):
try:
meth = d['_'.join([arg.__class__.__name__ for arg in args])]
except KeyError:
raise TypeError, 'No multimethod for type(s) %r' % map(type, args)
else:
return meth(self, *args)
return multi
class multimethod:
__metaclass__ = _multimethod
This is only very lightly tested. Extending this to cope with subclasses of
types, etc, is left as an exercise for the reader.
FWIW, here is what I tested it with:
if __name__ == '__main__':
class C:
class __mul__(multimethod):
def int(self, other):
return 'Integer multipication!'
def C(self, other):
return 'Selfness squared!'
class test(multimethod):
def int_str(self, i, s):
return 'Testing %r, %r' % (i, s)
c = C()
print c * 1
print c * c
try:
print c * "x"
except TypeError, e:
print e.args[0]
print c.test(2, 'two')
try:
print c.test('x', 'y')
except TypeError, e:
print e.args[0]
-Andrew.
More information about the Python-list
mailing list