[Python-ideas] values in vs. values out
Arnaud Delobelle
arnodel at gmail.com
Mon Jan 17 17:39:32 CET 2011
On 17 January 2011 15:04, Luc Goossens <luc.goossens at cern.ch> wrote:
> Hi all,
>
> Thanks to everybody for your feedback!
> So I guess the answer to my question (which - I noticed just now - did not
> end with a question mark), is ... no.
>
>> If your function is returning a bunch of related values in a tuple, and
>> that tuple keeps changing as you re-design the code, that's a code smell.
>
> the use cases I have in mind are the functions that return a set of weakly
> related values, or more importantly report on different aspects
> of the calculation;
> an example of the first is a divmod function that returns the div and the
> mod while callers might only be interested in the div;
> examples of the latter are the time it took to calculate the value, possible
> warnings that were encountered, ...
>
> like the good old errorcode/stdout/stderr trio
>
>> [various workarounds suggested]
>
>
> the problem with (all) the workarounds that were suggested is that they help
> with migrating from 2 to more return values;
> for the 1 to 2 case (the most common case) they don't help a lot, as the
> amount of work to put the workaround in place exceeds the amount of work to
> cope
> with the migration directly;
> I would say it is a requirement that the simple case of single variable gets
> single (or first) return value, retains its current simple notation
>
>
>> If the system automatically ignored "new" return values (for whatever
>> "new" might mean), I think it would be too easy to miss return values that
>> you don't mean to be ignoring.
>
>
> this I guess is only valid in the case where multiple return values are so
> strongly related they probably should be an object instead of a bunch of
> values
>
>
>> So it would be neat if you could do:
>>
>> (a, b, c=3) = func(...)
>
> or adding keywords to the mix
>
> a, b, c = kw1, d = kw2 (defval2) = function(...)
>
>
> now for the can of worms ...
>
> - one would need some syntactic means to distinguish the returning of two
> values from the returning of a single pair with two values
> - there's a complication with nested function calls (i.e. fun1 ( fun2(...),
> fun3(...)); the only simple semantic I could associate with
> this, is to simply drop all return values except for the first, but that is
> incompatible with returning the full return value of a function without
> needing to manipulate it
LISP has a notion of multiple return values. I can't easily find an
authoritative reference, but here is a short explanation:
http://abhishek.geek.nz/docs/features-of-common-lisp/#Multiple_values
Based on this, you could define a decorator class:
class multiple_values:
def __init__(self, f):
self.f = f
def __call__(self, *args, **kwargs):
return self.f(*args, **kwargs)[0]
def all_values(self, *args, **kwargs):
return self.f(*args, **kwargs)
@multiple_values
def div(x, y):
return x//y, x%y
Then:
>>> q = div(10, 3)
3
>>> q, r = div.all_values(17, 5)
--
Arnaud
More information about the Python-ideas
mailing list