PEP 318

Joe Mason joe at notcharles.ca
Wed Mar 24 08:55:42 EST 2004


In article <du7lllqfkce.fsf at lehtori.cc.tut.fi>, Ville Vainio wrote:
>    Andrew> Which is to say, I don't understand how that can work --
>    Andrew> the first definition of foo gets clobbered.
> 
> Yes, the name 'foo' gets clobbered every time, but the decorator
> always returns the *dispatcher* that is capable of dispatching the
> call to the correct definition of 'foo'. The dispatcher preserves the
> references to the callables, so they don't get decreffed out of
> existence.

Except the dispatcher gets clobbered by the second "def foo".  Unless it's held
in a global and looked up by name...

That might be something worth thinking about.  Right now, you can always do this:

class C:
    def foo(self, other):
        ...
    foo2 = multimethod(Matrix, Matrix)(foo)

    def foo(self, other):
        ...
    foo2 = multimethod(Matrix, Vector)(foo)

    foo = foo2
    undef foo2

The decorator syntax is less flexible.  But the whole problem goes away
if the decorators are applied between the creation of the function and
the binding: 

1. make an anonymous function
2. if there are decorators pass it through each in turn, replacing the
function with the return value
3. bind the result to the name

However, that means the name is unavailable inside the decorators.

>    Andrew> You *could* have a global registry that's keyed off
>    Andrew> func_name, as you suggest, but that doesn't work in
>    Andrew> general... what if I later have:
> 
>    Andrew> class C2:
>    Andrew> def foo(self, other):
>    Andrew> ...
>    Andrew> foo = multimethod(Long, String)(foo)
> 
>    Andrew> How is the registry not going to help distinguish between
>    Andrew> the foo methods from C, and the foo methods from C2?

Well, obviously you use the mangled name.  The real problem comes when
you actually do want to throw your multimethod away and use a brand new
foo.

Joe



More information about the Python-list mailing list