Argument Precedence (possible bug?)

Steven D'Aprano steve at REMOVETHIScyber.com.au
Sun Mar 5 14:36:14 CET 2006

```On Sun, 05 Mar 2006 04:45:05 -0800, vbgunz wrote:

> Hello all,
>
> I am just learning Python and have come across something I feel might
> be a bug. Please enlightenment me... The following code presents a
> challenge. How in the world do you provide an argument for *arg4?
>
> ## ============================================================
> def argPrecedence(par1, par2=0, par3=0, *par4, **par5):
>     print 'par1 =', par1, ' # positional argument'
>     print 'par2 =', par2, ' # keyword argument'
>     print 'par3 =', par3, ' # keyword argument'
>     print 'par4 =', par4, ' # argument converted to tuple'
>     print 'par5 =', par5, ' # argument converted to dictionary'

No, you are confused about * and ** arguments. They don't convert
arguments, they collect them.

def f(a, b=0, *args, **kwargs):
print "a =", a
print "b =", b
print "args =", args
print "kwargs =", kwargs

Now call the function different ways, and see which will work and which
won't.

f(1)
f(1, 2)
f(1, b=2)
f(a=1, b=2)
f(b=2, a=1)

Notice that this does not work:

f(b=3)

Do you understand why not?

Now look at these calls:

f(1, 2, 3)
f(1, 2, 3, 4, 5, 6)
f(1, 2, 3, 4, 5, 6, foo=7, bar=8)

In the function definition f(a, b=0, *args, **kwargs), a must be supplied,
b has a default value so it can be left out. Both a and b can be provided
as positional arguments like f(2, 3) or as keyword arguments.

Any _extra_ positional arguments are collected into a tuple called args,
and any _extra_ keyword arguments are collected into a dictionary called
kwargs. Of course you can use any names you like.

Hope this helps,

--
Steven.

```