What is the "Unpacking Arguments List" rule?

Jach Fong jfong at ms4.hinet.net
Sun Jun 3 20:18:42 EDT 2018


I had read "More on Defining Functions" sections of "The Python
Tutorial" carefully yesterday. One thing in the example code(Re: How can
an int be '+' with a tuple?) puzzles me again. It's the line 19:
     ....
     def progress(*any):
         threadQueue.put((onProgress, any + context))
     action(progress=progress, *args)  # line 19, it calls threadaction 
function
     ....
     def threadaction(id, reps, progress):
     ....

""" below was quoted from the document
4.7.2. Keyword Arguments
     ...
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
     ...

but all the following calls would be invalid:
     ...
parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
     ...

4.7.3. Arbitrary Argument Lists
     ...
def write_multiple_items(file, separator, *args):
     ...
Normally, these variadic arguments will be last in the list of formal
parameters, because they scoop up all remaining input arguments that are
passed to the function.
     ...

4.7.4. Unpacking Argument Lists
The reverse situation occurs when the arguments are already in a list or
tuple but need to be unpacked for a function call requiring separate
positional arguments.
     ...
 >>> args = [3, 6]
 >>> list(range(*args))
"""

I can't understand why line 19 works? Didn't it violate the rule of
"# non-keyword argument after a keyword argument"? and why a more
reasonable look syntax gets an error?

     action(*args, progress)
                      ^
SyntaxError: only named arguments may follow *expression  File 
"test.py", line 19

The only reason I can guess is that it checks with the rule in 4.7.3 
which is really unrelated. The "*any" notation used in different places
with different meaning, such as defining arbitrary argument, unpacking
argument or even in an assignment(a,*b=any). Maybe it will be better to
stop this syntax checking and lets both statements below valid:-)

     action(progress=progress, *args)
     action(*args, progress)


Best Regards,
Jach Fong


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus




More information about the Python-list mailing list