[Python-ideas] Positional only arguments
Ron Adam
rrr at ronadam.com
Tue May 22 04:05:17 CEST 2007
Jim Jewett wrote:
>> What I would like is for unpack to be '^' instead of '*', then you would
>> have...
>
> My first reaction was negative -- but then I remembered that I was
> caught by this trap myself more than once, because of the asymmetry
> between pack and unpack, with * magically doing the normally-right
> thing.
>
> So now I wonder if I wouldn't like if after all, and I'm instead
> picking at the presentation, so you can make a stronger case.
Yes, it's gotten me a few times as well. Usually when I have a class and
some of the methods are accepting *args, **kwds, and some aren't. Then I
find I'm packing arguments in some cases and unpacking them in others in
the same subclass, and the methods definitions are not on the same page so
it isn't immediately obvious I got them mixed up. As I said it isn't a
computer issue, it's a human interface issue.
> On 5/21/07, Ron Adam <rrr at ronadam.com> wrote:
>
>> Now if we use ^ for unpacking, and * for packing, it reduces the
>> number of
>> meanings for the '*' and fixes the context of positional and keyword only
>> arguments.
>
>> def f(a, ^(b=2, c=3), *rest): b and c are positional only here.
>
> I don't think there should ever be positional-only arguments *after* a
> keywordable argument. Perhaps
>
> # a is a mandatory positional argument
> # b is an optional positional argument
> # c can be passed as a keyword, or as the third positional argument
> def f(^a, ^b=2, c=3, *rest):
>
> Or were you suggesting a tuple of the positional-only arguments, like
>
> # a is a mandatory positional argument
> # b is an optional positional argument
> # c can be passed as a keyword, or as the third positional argument
> def f(^(a, b=2), c=3, *rest):
Ah, ok, I see what I missed. I think I got optional args mixed up with
positional args in my mind. Not quite the same thing.
So yes, the second example fits what I was trying to think of better.
# a is mandatory, positional
# b is optional, positional
# c is optional, positional, or by keyword
# d is mandatory, keyword only
# e is optional, keyword only
def f(^(a, b=2), c=3, ^^(d, e=5)):
Of course it could be interpreted a bit differently given the unpacking
context.
# x is a two tuple (a, b)
# y is a single value, c
# z is a dict, {'d':4, 'e':5}
result = f(x, y, z)
Which solves a different problem entirely. ;-)
It allows you to specify unpacking behavior in the definition instead of
requiring it on the calling side.
So I guess I'd have to fall back to the semi-colon as the positional only
and keyword only designators.
def f(a, b=2; c=3; d, e=5):
Or alternately use the colon as it is used in slices.
def f(a, b=2: c=3: d, e=5):
I'd almost rather change the slices to semicolons and keep the colon unique
and with only one purpose.
And ...
def f(a, b=2, c=3)
would be equivalent to...
def f(; a, b=2, c=3;): No positional only, no keyword only
Anyway, I'm not sure there is a simple way to do this. Sigh...
>> There is the possibility of extending this for use in other ways as well.
>>
>> xlist = [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
>>
>> alist = [^x for x in xlist]
>>
>> This would have list "extend" behavior instead of list "append" behavior.
>
> So alist == [1, 2, 3, 4, 5, 6, 7, 8, 9]?
Exactly.
Cheers,
Ron
More information about the Python-ideas
mailing list