Types of function arguments in python

neotam Avatar

Python Function - Argument Types
Posted on :

Unlike many other programming languages python supports multiple types formal arguments in the function definition. It is one of the flexibility that python offers.

Types of function (formal) arguments that python supports,

Following picture illustrates these different types of arguments by their order according to the syntax and how we can use them.

Python Function Definition, Arguments Kind and Order
Python Function Definition, Arguments Kind and Order

Let’s see these arguments in detail. Before we proceed you need to know what are parameters and arguments and difference between formal arguments and actual arguments.

Parameters vs Arguments

It is recommended to understand what are arguments and parameters before proceeding further. Vocabulary parameters and arguments are not limited to python but they are same across different programming languages.

Arguments are values that are passed into function(or method) when the calling function
Parameters are variables(identifiers) specified in the (header of) function definition

Following image shows difference between parameters and arguments.

Programming - Function Parameters vs Arguments
Function Parameters VS Arguments

With function call arguments are what you pass into the function parameters. Or it can be said, parameters are names(variables) in a function(or method) definition that specifies types of arguments that the function can accept.

In call-by-value programming languages arguments are copied into parameter(variables) by their position

Python is based on call by object reference or sometimes called call by sharing, where reference of formal arguments will be assigned to actual parameters

These words are sometimes used interchangeably but aware of context

Python supports two kind of arguments

  • Positional arguments
  • keywords arguments

And python supports total five kind of parameters

  • positional or keyword
  • positional only
  • keyword only
  • variable positional (var-positional)
  • Variable Keyword

These different kind of arguments and parameters is what we are going to see later in this article

Formal vs Actual Arguments

Formal Arguments VS Actual Arguments

Formal arguments are identifiers used in the function definition to represent corresponding actual arguments.
Actual arguments are values(or variables)/expressions that are used inside the parentheses of a function call.

Above definition and terminology of Formal/Actual arguments is same across different programming languages.

Regular Positional Arguments

These are regular positional argument as it sounds regular. Regular positional arguments are very much similar to arguments that you see in any kind of programming language. These are just (variables) identifiers that values of actual arguments are copied to formal arguments by their position in the function call *.

def add(a, b):
return a + b
# function call
add(2, 3)

If count of actual arguments and formal arguments don’t match interpreter will throw TypeError exception

>>> add(2)
Traceback (most recent call last):
File "", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'b'

Default Arguments

Default arguments allow us to provide defaults for corresponding formal arguments in the function definition. Python uses these defaults if corresponding actual arguments are not passed in the function call.

Default arguments should always be followed by non-default arguments in function definition

def greetings(name, msg="Welcom, Good Morning"):
message = "Hello {}! {}".format(name, msg)
print(message)

As we can see here, the argument msg got it’s default in the function definition. If the argument msg is not passed in the function call it’s default given in the definition will be used. So called default arguments.

>>> greetings("neo")
Hello neo! Welcom, Good Morning

Default arguments are mandatory to pass in a function call. If default arguments are not passed, corresponding default parameter values will be used. To override defaults pass corresponding arguments in a function call

The concept of default arguments is very powerful and helpful when writing APIs or utility function. We can define a function with some default parameters which are not required to make a function but can be used by those who want more control. Let’s look at following example

For suppose we are writing a function to fetch home page of arbitrary website . As we know default port for HTTP is 80. We can write a function in such a way that, which will accept one positional argument which address and one default argument which port.

def fetchHomePage(domain, port=80):
    import urllib.request
    url = f"http://{domain}:{port}/"
    page = urllib.request.urlopen(url).read()
    print(page)

Calling above function by excluding port argument, where default value 80 will be used

fetchHomePage("example.com")

Let’s say, your web site is running on port 8000. In such a case we can make function call with port argument value 8000 which overrides default value 80

fetchHomePage("example.com", port=8000)

If default arguments are specified prior non-default arguments it is a syntax error with following message

SyntaxError: non-default argument follows default argument

Following code causes a syntax error since non-default argument follows default argument

def foo(a=3, b, c):  #invalid default arguments order/ syntax error 
    pass 

Keyword Arguments

Keyword arguments are passed by it’s name instead of their position as opposed to positional arguments in the function call. As a result we don’t have to mind about position of arguments when calling a function.

Keyword arguments are also referred as named arguments.

Keyword arguments should always be followed by positional arguments in the function call

Let’s call above defined function greetings using keyword arguments

greetings(name="neo", msg="Welcome")

Since we are passing arguments by their names/keywords order or position doesn’t matter

greetings(msg="Welcome", name="neo")

We can mix both positional and keyword arguments but keyword arguments should follow positional arguments

greetings("neo", msg="Welcome")

If you break the rule and pass arguments in such a way that positional arguments follow keyword arguments which is a syntax error.

>>> greetings(msg="Welcome", "neo")
... ...
SyntaxError: positional argument follows keyword argument

Variable Length Positional Arguments

Variable length positional arguments are useful when we are not certain about number of arguments that are required in the function definition or function would receive. It is quite useful to write functions that take countless number of positional arguments for certain use cases.

Syntax to receive variable length positional arguments

def foo(a, b, c, *varargs):
....

Python first fills the slots given formal arguments by passed positional actual arguments. Any left over actual (positional) arguments are captured by python as a tuple, which is available through variable which is having prefixed * in the function definition.

As we can see in the above syntax. variables a, b, c need to be filled by actual arguments any left over passed arguments can be accessed as tuple using varargs.

def foo(a, b, c, *varargs):
print("Regular Positional Arguments", a, b, c)
print("Variable Length Positional arguments", varargs)
>>> foo(2, 3, 4)
Regular Positional Arguments 2 3 4
Variable Length Positional arguments ()

Since there are no extra positional arguments are passed in the above function call. The variable varargs is a empty tuple

>>> foo(1, 2, 3, 4, 5, 7)
Regular Positional Arguments 1 2 3
Variable Length Positional arguments (4, 5, 7)

As you can see in the above function call, left over arguments are added to tuple and can be accessed using given variable varargs.

You can unpack and pass each element in the sequence as individual argument just by prefixing * in front of the sequence

>>> foo(1, 2, 3, *'hello')
Regular Positional Arguments 1 2 3
Variable Length Positional arguments ('h', 'e', 'l', 'l', 'o')

Where as, if you don’t put * in front of a string or sequence in the function call. Which will be taken as single argument as a whole.

>>> foo(1, 2, 3, 'hello')
Regular Positional Arguments 1 2 3
Variable Length Positional arguments ('hello',)

Positional Only Parameters

Positional-only parameters syntax was added in Python 3.8 . This feature allows to define a function to accept certain parameters positional only and those parameters cannot be passed as keyword arguments in a function call.

Positional-only and other parameters are differentiated using forward slash (/) in a function definition. All parameters prior forward slash ( / ) are positional only and parameters followed by forward slash ( / ) can be any kind of (mixed)parameters. Passed arguments in a function call are mapped to parameters solely based on their position.

Positional-only parameters are with out an externally usable name up on calling a function. Arguments are mapped to parameters based on their position for positional-only parameters

All parameters prior forward slash (/) in function definition are positional only

Following simple code explains function definition with position only arguments

def foo(a, b, /, x, y):
   print(f"positional only arguments: {a}, {b}")
   print(f"positional or keyword arguments: {x}, {y}")

In the above example, parameters a and b are positional only while x and y can be either positional or keyword arguments

Following function calls are valid

foo(2, 3, 4, 5)
foo("a", "b", "x", y=99)
foo(10, 20, x=66, y=99)

Following is a invalid function call

#Arguments a and b must be positional only 
foo(a=3, b=30, x=99, y=999)

Following example shows positional only parameters mixed with other

Function can be defined to accept only positional arguments by suffixing forward slash (/) in parameter list

def  power(x, y, /):
   return x ** y 

In the above example parameters x and y have to be passed as positional arguments in function call. Calling the above function by keyword arguments raises TypeError as follows

TypeError: power() got some positional-only arguments passed as keyword arguments: ‘x, y’

keyword Only Arguments

Keyword Only arguments are new feature in python 3. Main purpose of keyword only arguments is to be able to pass arguments by it’s keyword only for selected arguments.

Read More here at python keyword only arguments

There are two types of keyword only arguments

Variable Length Keyword Arguments

Variable length keyword arguments are very much similar to variable length positional arguments. It is the mechanism to accept variable length arguments in the form keyword arguments which is useful if we are not certain about number of keyword arguments that function receives. Python captures all extra keyword arguments as dictionary and makes it available by name(variable) which is prefixed by ** in the function definition.

Variable length keyword arguments can also be referred variable length named arguments

Variable Length Keyword Arguments Syntax

def foo(a, b, c, **kwargs):
. . .

kwargs gets left over keyword arguments after formal arguments are filled up by passed keyword arguments.

def printKWArgs(a, b, c, **kwargs):
print("Regular Positional Arguments", a, b, c)
print("Variable Length keyword arguments", kwargs)
>>> printKWArgs(2, 3, c=5)
Regular Positional Arguments 2 3 5
Variable Length keyword arguments {}

In the above function call since we haven’t passed any extra keyword arguments variable kwargs is a empty dictionary.

>>> printKWArgs(2, 3, c=4, d=9, e=10)
Regular Positional Arguments 2 3 4
Variable Length keyword arguments {'d': 9, 'e': 10}

In the above function call left over keyword arguments d and e can be accessed through variable kwargs which is dictionary. Where key will be the passed keyword name and value will be value given for corresponding keyword in the function call.

Combining both varargs and kwargs

You can use both variable length positional arguments and variable length keyword arguments combined.

def foo(a, b, *varargs, **kwargs):
...

Different Types Of Function Arguments In Action

Here is the simple function which makes use of all kind of arguments and prints passed arguments by it’s kind

Let’s call the above function by passing these several kind of arguments

printArgsByKind(1, 2, 3, 3.15, float, 4, 5, 6, operation="count", return_type=int, abc=3, xyz=9)

The above function call would print the given arguments by it’s kind as follows,

Regular Positional Arguments a: 1, b: 2, c: 3
Default Arguments default: 3.15, intype: <class 'float'>
Variable length positional arguments(tuple) more: (4, 5, 6)
Non-Default Keyword-Only Arguments operation: count, return_type: <class 'int'>
Default Keyword-Only Arguments print_result: False, ignore_exception: True
Variable length keyword arguments kwargs: {'abc': 3, 'xyz': 9}

Leave a Reply

Your email address will not be published. Required fields are marked *