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

Is now available as a print book: Amazon

pythoncover


Contents

  1. Hello Python World
  2. Variables, Objects and Attributes
  3. The Function Object
      Extract - Function Objects
  4. Scope, Lifetime and Closure
      Extract - Local and Global
  5. Advanced Functions
      Extract - Parameters ***NEW
      Extract - Decorators 
  6. Class Methods and Constructors
      Extract - Objects Become Classes
  7. Inside Class
  8. Metaclass
  9. Advanced Attributes
      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 
  15. More Magic - Operator Overloading

 

Advanced Attributes

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

square

 



 

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 )