On Thu, 24 Mar 2011 23:30:29 -0700, Paddy wrote: > Hi, I just found the following oddity where for function fsf1 I am > forced to use a named parameter for correct evaluation and was wondering > why it doesn't work, yet the example from the docs of wrapping int to > create basetwo doesn't need this? The example: > >>>> from functools import partial >>>> basetwo = partial(int, base=2) >>>> basetwo('10010') > 18
When you call basetwo, it gets passed one positional argument and one keyword argument. The positional arguments are bound from left to right, as is normal in Python: int expects to be called like int(a, [base=]b) int gets passed two arguments: int('10010', base=2) so all is well. The string '10010' gets bound to the first argument, and the keyword argument 2 gets bound to the second. >>>> def fs(f, s): return [f(value) for value in s] > >>>> def f1(value): return value * 2 > >>>> s = [0, 1, 2, 3] >>>> fs(f1, s) > [0, 2, 4, 6] All these f's and s's give me a headache. It's easier to discuss if you give them distinctive names: spam, ham, eggs are conventions in Python, foo, bar, baz in some other languages. >>>> 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' fs expects to be called like fs(f, s). It gets called with one positional argument, [0,1,2,3], which gets bound to the left-most parameter f, and one keyword argument, f1, which *also* gets bound to the parameter f (only by name this time, instead of by position). >>>> # BUT >>>> fsf1(s=s) > [0, 2, 4, 6] Now, because you're calling fsf1 with keyword argument, fs gets called: fs(f=f1, s=[0,1,2,3]) -- Steven -- http://mail.python.org/mailman/listinfo/python-list