functools.partial doesn't work without using named parameter

Ian Kelly ian.g.kelly at gmail.com
Fri Mar 25 03:03:11 EDT 2011


On Fri, Mar 25, 2011 at 12:30 AM, Paddy <paddy3118 at googlemail.com> wrote:
>>>> def fs(f, s): return [f(value) for value in s]

Note that your "fs" is basically equivalent to the "map" builtin,
minus some of the features.

>>>> fsf1 = partial(fs, f=f1)
>>>> fsf1(s)
> Traceback (most recent call last):
>  File "<pyshell#24>", line 1, in <module>
>    fsf1(s)
> TypeError: fs() got multiple values for keyword argument 'f'
>>>> # BUT
>>>> fsf1(s=s)
> [0, 2, 4, 6]
>>>>
>
> Would someone help?

When you invoke a partial application, it just adds the positional
arguments passed to partial to the positional arguments passed in, and
it adds the keyword arguments passed to partial to the keyword
arguments passed in.  Using partial to specify f as a keyword argument
does not change the fact that it is also the first positional
argument.  So the call `partial(fs, f=f1)(s)` is equivalent to `fs(s,
f=f1)`.  In the latter case, 's' is being passed positionally as the
first argument (i.e. 'f') and 'f1' is being passed by keyword as the
'f' argument, resulting in 'f' being passed in twice.  The partial
application is equivalent, so it does the same thing.

The call `partial(fs, f=f1)(s=s)`, however, is equivalent to `fs(f=f1,
s=s)`, which is fine.

Moral of the story: if you pass in an argument by keyword, then the
following arguments must be passed by keyword as well (or not at all),
regardless of whether you're using partial or not.



More information about the Python-list mailing list