Programmer's Python - Parameters
Written by Mike James   
Monday, 11 January 2021
Article Index
Programmer's Python - Parameters
Variable Parameters

Variable Parameters

Suppose you want to define a function which can accept any number of parameters. The solution to this is to specify a parameter of the form *name. In this case all of the arguments, as many as supplied, are packed into a tuple ready for you to process.

For example:

def sum(*nums):
    total=0
    for n in nums:
        total=total+n    
    return total

Notice that the parameter when used within the function doesn’t have the * prefix. You can now call sum with as many numbers to add up as you require:

print(sum(1,2,3,4,5,6))

You can also specify a variable set of parameters after a number of positional parameters.

For example:

def sum(a,b,*nums):
    total=a+b
    for n in nums:
        total=total+n    
    return total
print(sum(1,2,3,4,5))

In this case 1 and 2 are stored in a and b, and the remainder of the arguments are stored in nums as a tuple.

You obviously can’t have any positional parameters beyond a catch all *name but you can have keyword only parameters. For example:

def sum(*nums,a,b):
    total=a+b
    for n in nums:
        total=total+n    
    return total

If you just call this version of sum with positional arguments you will see an error message. You have to call this with named parameters:

print(sum(1,2,3,4,5,a=6,b=7))

It doesn’t matter where you specify the named parameters but you have to do it – hence the term “keyword only” parameter.

You can also set defaults for keyword only parameters.

For example:

def sum(*nums,a=1,b):
    total=a+b
    for n in nums:
        total=total+n    
    return total

Now a is still a keyword only parameter but if you don’t specify a value for it when you call the function, the default will be used. Notice that if you want keyword only parameters to be optional you have to supply a default:

print(sum(1,2,3,4,5,b=7))

and you cannot omit b because it has no default.

Keyword only parameters are stored in the __kwdefaults__ attribute of the function as a dictionary object.

For example:

print(sum.__kwdefaults__)

prints:

{'a': 1}

What about a variable number of arbitrary keyword parameters?

In the same way that *name stores any number of positional parameters in a tuple **name will store any number of keyword parameters in a dictionary.

For example:

def sum(**namedNums):
    total=0
    for name,value in namedNums.items():
         total=total+value
         print(name,value)
    return total

creates a function that can only be called using keyword parameters and you can make up the keywords when you call the function.

For example:

print(sum(one=1,two=2,three=3))

prints one 1, two 2, three 3 and the sum of the values, 6.

You can also define a function that has any number of positional parameters and any number of keyword parameters by using *name and **name together. Notice that in this case *name has to come first and you can also have some positional parameters as long as they come before *name.

For example:

def sum(a,b,*nums,**namedNums):
    total=a+b
    for value in nums:
        total=total+value
    for name,value in namedNums.items():
        total=total+value
        print(name,value)
    return total

Now you have to call sum with two positional parameters, but after that you can have as many positional or keyword parameters you want to use.

For example:

print(sum(1,2,3,4,one=1,two=2,three=3))

in this case 1 is stored in a, 2 in b, (3,4) in nums, and the keyword parameters are stored in namedNums.

Unpacking Into Parameters

You can think of *name and **name as being packing operations. They pack the positional and keyword parameters into tuples and dictionaries respectively.

It sometimes happens that what you have is already packed into a tuple or a dictionary and you want to pass it to a function as a parameter list. The easiest solution is to use the unpacking operators * and ** which unpack a tuple or a dictionary respectively.

For example:

def sum(a,b):
    total=a+b
    return total
tuple=(1,2)
print(sum(*tuple))

In this case the tuple (1,2) is unpacked into the parameters a and b.

If there are too many parameters after unpacking you will generate an error:

tuple=(1,2,3,4)
print(sum(*tuple))

generates:

TypeError: sum() takes 2 positional arguments but 4 were given

You can of course avoid this by using the * operator in the function definition:

def sum(a,b,*nums):
    total=a+b
    return total

Any unused parameters that result from the unpacking are now packed into a tuple referenced by nums.

The same idea works with dictionaries and keyword parameters:

dict={"a":1,"b":2}
print(sum(**dict))

In this case dict is unpacked into a and b with values 1 and 2 respectively.

As with tuples the parameters have to exist but you can repack the dictionary into a parameter using **name.

Not in this extract:

  • Return Values

  • Docstrings and Annotations

  • Decorators

  • Making the Wrap Transparent – functools

  • Multiple Decorators

  • Decorator Factories

 

Summary

  • Python allows defaults for parameters to be set.

  • You can call functions using parameters as keyword parameters.

  • Specifying *name is a way of using a variable number of positional parameters – any arguments supplied that are not used by positional parameters are stored in *name as a tuple.

  • Specifying **kwname works in the same way as *name but any unused keyword arguments are stored in it as a dictionary.

  • Docstrings can be used to create rudimentary documentation for a function.

  • Annotations can be applied to parameters and return values – usually to indicate the type.

  • Decorators are functions that take a single function as an argument and return a single function – they are used to transform functions.

  • A decorator is written as @dec in front of a function definition and this is equivalent to f=dec(f) where f is the name of the function.

  • Multiple decorators are applied starting with the decorator closest to the function working up the page.

  • You can also use a decorator factory @decfac(parameters) with parameters. It is evaluated at once and has to return a decorator which is applied to the function in the usual way.

 

Programmer's Python
Everything is an Object
Second Edition

Is now available as a print book: Amazon

pythonObject2e360

Contents

  1. Get Ready For The Python Difference
  2. Variables, Objects and Attributes
  3. The Function Object
  4. Scope, Lifetime and Closure
      Extract 1: Local and Global ***NEW!
  5. Advanced Functions
  6. Decorators
  7. Class, Methods and Constructors
      Extract 1: Objects Become Classes 
  8. Inside Class
  9. Meeting Metaclasses
  10. Advanced Attributes
  11. Custom Attribute Access
  12. Single Inheritance
  13. Multiple Inheritance
  14. Class and Type
  15. Type Annotation
  16. Operator Overloading
  17. Python In Visual Studio Code

 Extracts from the first edition

<ASIN:1871962749>

<ASIN:1871962595>

<ASIN:1871962765>

Related Articles

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget

The Python Dictionary

Arrays in Python

Advanced Python Arrays - Introducing NumPy

espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner

<ASIN:1871962587>

 



Last Updated ( Wednesday, 13 January 2021 )