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

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
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

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

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)

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)

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
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

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.

## Is now available as a print book: Amazon

#### Contents

1. Hello Python World
2. Variables, Objects and Attributes
3. The Function Object
Extract - Function Objects
Extract - Local and Global
Extract - Parameters ***NEW
Extract - Decorators
6. Class Methods and Constructors
Extract - Objects Become Classes
7. Inside Class
8. Metaclass
Extract - Properties
10. Custom Attribute Access
Extract -  Custom Attributes
Extract -  Default Methods
11. Single Inheritance
12. Multiple Inheritance
13. Class and Type
Extract - Class
14. Type Annotation
Extract - Type Annotation

## 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