Looking for the best way to translate an idiom

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Sun Dec 14 11:22:11 EST 2008


Paul Moore a écrit :
> I'm translating some code from another language (Lua) which has
> multiple function return values. So, In Lua, it's possible to define a
> function
> 
>     function f()
>         return 1,2,3
>     end
> 
> which returns 3 values. These can then be used/assigned by the caller:
> 
>     a,b,c = f()
> 
> So far, much like Python, but the key difference is that in Lua,
> excess arguments are ignored - so you can do
> 
>     a = f()
> or even
>     a = f() + 1
> 
> where in the latter, a is 2 (as addition only needs 1 argument, so the
> extra ones are discarded).
> 
> This results in the code which I'm trying to translate having
> functions which return multiple arguments, the first of which is the
> "main" result, and the following values are "extra" results
> (specifically, the position at which a match is found, followed by the
> "captured" values of the match).
> 
> I'm trying to find a natural equivalent in Python. So far, I've
> considered the following:
> 
> - return a tuple (pos, captures). This is messy, because you end up
> far too often unpacking the tuple and throwing away the second value

if you only want the first returned value, you can just apply a slice:

def f():
    return 1,2,3

a = f()[0] + 1

> - return an object with pos and captures attributes. This is better,
> as you can do match(...).pos to get the position alone, but it doesn't
> really feel "pythonic" (all those calls with .pos at the end...)

FWIW, Python 2.6 has NamedTuple objects...

> - have 2 calls, one to return just the position, one to return both.
> This feels awkward, because of the 2 method names to remember.

You forgot one solution: passing a flag to the function to specify if 
you want only the main result or the extra ones as well, and give this 
flag the appropriate default value depending on most common use case.

> To make things worse, Lua indexes strings from 1, so it can use a
> position of 0 to mean "no match" - so that a simple "did it match?"
> test looks like if (match(....))... - where in Python I need if
> (matchpos(...) != -1)... (Although if I return a match object, I can
> override __nonzero__ to allow me to use the simpler Lua form).
>
> Can anyone suggest a good idiom for this situation? At the moment, I'm
> returning a match object (the second option) which seems like the
> least bad of the choices (and it mirrors how the re module works,
> which is somewhat useful). But I'd like to know what others think. If
> you were using a pattern matching library, what interface would you
> prefer?

The one that happens to be the most simple for the most common usecase, 
while still providing support for more advanced stuff.

> I suspect my intuition isn't accurate here, as most of the use I've
> made of the library is in writing tests, which isn't typical use :-(

So perhaps you should start writing some real-life code ?

> Thanks for any assistance.

Not sure I've been that helpful. Sorry...



More information about the Python-list mailing list