On Sat, 2008-08-30 at 12:00 +0200, [EMAIL PROTECTED] wrote:
> 
> Message: 2
> Date: Sat, 30 Aug 2008 10:09:36 +0100
> From: eShopping <[EMAIL PROTECTED]>
> Subject: Re: [Tutor] dynamic argument lists
> To: tutor@python.org
> Message-ID: <[EMAIL PROTECTED]>
> Content-Type: text/plain; charset=us-ascii; format=flowed;
>         x-avg-checked=avg-ok-571D6DEA
> 
> Bob, Kent
> 
> thanks for the suggestions.  Bob made the comment "If there is no 
> compelling requirement that myfunc's argument be in the form **kwargs 
> ...", but I'm afraid I don't understand the difference between
> 
> myfunc (**kwargs)
> 
> and
> 
> myfunc (kwargs)
> 
> Would someone mind explaining this?  I never managed to find a 
> satisfactory explanation for what "**" means!

First you have to understand what ** in a function definition means:
def func(positionalArg, *excessPositionalArg, **excessNamedArg):
    ...

positionalArg is the regular arguments you use, it is accessible by
placing arguments at their respective position and the name it is
assigned to, e.g.

def func1(arg1, arg2, arg3):
    print arg1, arg2, arg3
func1(1, 2, 3)
# 1 2 3

func1(1, 2, 3, 4)
# Wrong number of argument Error

func1(1, arg3 = 2, arg2 = 3)
# 1 3 2

excessPositionalArg is a list of positional arguments that doesn't fit
in the regular positional argument, e.g.

def func2(arg1, arg2, *epa):
    for arg in epa:
        print arg,
func2(1, 2, 3, 4, 5, 6, 7)
# 3 4 5 6 7

last, is excessNamedArg. As we have learned, there are two ways to
access an argument, by its position and by its names,
excessNamedArgument is a dictionary containing the named arguments that
aren't explicitly specified in the function definition, e.g.

def func3(arg1, arg2, *args, **kargs):
    print arg1, arg2,
    for arg in args:
        print '[1 -- %s]' % arg,
    for key, value in kargs:
        print '[2 -- %s: %s]' % (key, value)

func3(1, 2, otherargs = 10):
# 1 2 [2 -- otherargs: 10]

func3(1, arg2 = 2, otherargs1 = 10, otherargs2 = 20)
# 1 2 [2 -- otherargs1: 10]
# [2 -- otherargs2: 20]

Now, to the question, then what is this:
d = {'a':10, 'b':20, arg2: 30}
func3(1, **d)
# 1 30 [2 -- a: 10]
# [2 -- b: 20]

compare:
func3(1, 2, d)
# 1 2 [1 -- {'a':10, 'b':20, arg2: 30}]

If you called it like func3(1, 2, **d), and d is a dictionary, then d
would be expanded and its key/value pair be considered as named
arguments to the function. OTOH, func3(1, 2, d) would pass the whole
dictionary to func3. Since in this case, we have declared a container
for excessPositionalArgument, d is treated as excessPositionalArgument,
if we haven't done that, an bad number of argument error would occur
because there is no more positional argument left.



_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to