Python Function Arguments

Table of Contents

Function Arguments

Positional Arguments

def company(name, year, state, country):
    print(name, year, state, country)

company("pythoneasy", 2018, "California", "US")
pythoneasy 2018 California US
The arguments are passed and assigned as per the position of the arguments.
Here "pythoneasy" is assigned to name, 2018 to year, "California" to state, "US" to country.

It is mandatory to pass the exact number of values to the function while calling it or else it will raise an error.
company("pythoneasy", 2018, "California")
TypeError: company() missing 1 required positional argument: 'country'

Keyword arguments

Functions can also be called using keyword arguments in the form of kwarg=value.
In this case the order or position of the keywords can be changed
Keyword arguments allow us to match by name, instead of by position.

def company(name, year, state, country):
    print(name, year, state, country)

company(year=2018, state="California", name="pythoneasy", country="US")
company(state="California", year=2018, name="pythoneasy", country="US")
company(country="US", year=2018, state="California", name="pythoneasy")
pythoneasy 2018 California US
pythoneasy 2018 California US
pythoneasy 2018 California US

We can mix positional and keyword arguments as follows

company("pythoneasy", year=2018, state="California", country="US")   #  1 postional and 3 keyword arguments
company("pythoneasy", 2018, state="California", country="US")          #  2 postional and 2 keyword arguments
company("pythoneasy", 2018, country="US", state="California")          #  2 postional and 2 keyword arguments. keyword arguments position can be random

Like the last function call above, the keyword arguments can be changed to any order.

Keyword arguments must follow positional arguments.

company(year=2018, state="California", country="US", "pythoneasy")

SyntaxError: positional argument follows keyword argument
Here "pythoneasy" is the positional argument

All the keyword arguments passed must match one of the arguments accepted by the function

company(name="pythoneasy", year=2018, district="California", country="US")

TypeError: company() got an unexpected keyword argument 'district'
Here name "district" is not available any of the function argument def company(name, year, state, country)

No argument may receive a value more than once.

 company(name="pythoneasy", name="python.org", state="California", country="US")

SyntaxError: keyword argument repeated
Here value for name passed 2 times

Default arguments

We can make selected function arguments optional by providing a default value to it.
We can specify a default value for one or more arguments while defining a function.
The argument for which default value is assigned, we do not need to pass any value until you require it.

def company(name, year, state, country="US"):
    print(name, year, state, country)

company("pythoneasy", 2018, "California")
pythoneasy 2018 California US
As there is no default value for name, year, state, it is mandatory to pass values for these while calling the function.
You can see that we have not passed value for country , but still it does not raise any error.
"country" is simply assigned a default value "US".

The default value will be overridden once we pass a positional value for "country" like below.
company("pythoneasy", 2018, "California", "United States")
pythoneasy 2018 California United States More Examples
def func(a, b, c=0, d=0):   # First 2 required
    print((a, b, c, d))

func(1, 2)              # prints: (1, 2, 0, 0)
func(1, d=1, b=0)       # prints: (1, 0, 0, 1)
func(a=1, b=0)          # prints: (1, 0, 0, 0)
func(c=1, b=2, a=3)     # prints: (3, 2, 1, 0)
func(1, 2, 3, 4)        # prints: (1, 2, 3, 4)

When the keyword arguments are used, order does not matter
The function caller must pass values for a and b, but they can be matched by position or by name (keyword arg)

The form name=value in caller is different than in the function header.
In function header it indicates the default value (say def func(d=0)) and in function call it the value passed for the name (say func(d=1))

Variable length arguments / Arbitrary Arguments

Sometimes we may need to pass more number of variable than we have specified while defining a function.
Python allows us to send arbitrary arguments to the function.
* and ** used to support the arbitrary arguments in python function both in function definition(header) or function call

On the function definition - collecting

Positional argument

To pass arbitrary keyword argument we can use * in function definition
 def foo(*args):
     print(args)

In this case you can send N number of positional arguments to function.
The arguments will be stored in the tuple named args in order which the arguments passed.
Remember args is just a name, you can use any name instead or args
Let us call the function with arbitrary arguments

foo(1)          # prints (1,)
foo(1, 2)       # prints (1, 2)
foo(1, 2, 3)    # (1, 2, 3)

Here args is just a tuple. So you can get the positional arguments by indexing.
Example

def foo(*args):
    print("Hostname is:", args[0])
    print("User is:", args[1])
    print("IP is:", args[2])

foo("pythoneasy.com", "John Doe", '10.24.124.12')
Hostname is: pythoneasy.com
User is: John Doe
IP is: 10.24.124.12

Keyword argument

To pass arbitrary keyword argument we can use ** in function definition
def foo(**args):
    print(args)

foo(a=1, b=2, k=3)  # prints {'a': 1, 'b': 2, 'k': 3}

The keyword arguments gets collected into args dictionary, which can be processed using normal dictionary.
Let us see this example
def foo(**args):
    print("Hostname is:", args.get('hostname'))
    print("User is:", args.get('user'))
    print("IP is:", args.get('ip'))

foo(hostname="pythoneasy.com", ip='10.24.124.12', user="John Doe") # Order is not mandatory for keyword arguments

Hostname is: pythoneasy.com
User is: John Doe
IP is: 10.24.124.12

let us combine both of them
Example 1

def foo(*args, **kargs):
    print("Hostname is:", args[0])
    print("User is:", kargs.get('user'))
    print("IP is:", kargs.get('ip'))


foo("pythoneasy.com", ip='10.24.124.12', user="John Doe")
Hostname is: pythoneasy.com
User is: John Doe
IP is: 10.24.124.12

Example 2
def foo(hostname, *args, **kargs):
    print("Hostname is:", hostname)
    print("User is:",  args[0])
    print("IP is:", kargs.get('user'))


foo("pythoneasy.com", '10.24.124.12', user="John Doe")

Hostname is: pythoneasy.com
User is: 10.24.124.12
IP is: John Doe

Here you can see args contains the extra positional arguments

When a combination of arbitrary arguments available python follows the below sequence while a function is called

  1. Assigns non keyword arguments by position.
  2. Assigns keyword arguments by matching names.
  3. Assigns extra non keyword arguments to *args tuple.
  4. Assigns extra keyword arguments to **kwrgs dictionary.
  5. Assigns default values to unassigned arguments in header/function defintition.

On the function calls - Unpacking arguments

While calling a function we can pass arbitrary arguments using * and ** and the python automatically unpacks them into individual arguments
Example
def foo(a, b, c, d):
    print(a, b, c, d)

args = (1, 2, 3, 4)
foo(*args)     # prints 1, 2, 3, 4

The elements in args matched with the order of the arguments in function definition i.e. a, b, c, d
So the number of elements args in should be exactly same as number of arguments, or else python will throw an error.
args = (1, 2, 3) # Here value d is missing
foo(*args)

TypeError: foo() missing 1 required positional argument: 'd'

Similarly using ** we can pass keyword arguments
Example 1

kw_args = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
foo(**kw_args) # prints 1, 2, 3, 4

Remember the keys in kw_args should be matched with arguments in function definition/header

kw_args = {'a': 1, 'b': 2, 'c': 3} # Here d is missing
foo(**kw_args)
TypeError: foo() missing 1 required positional argument: 'd'

Example 2

kw_args = {'a': 1, 'b': 2, 'c': 3, 'e': 4} # Here value for d is not provided, but an extra argument e passed
foo(**kw_args)

TypeError: foo() got an unexpected keyword argument 'e'
More Examples

def foo(a, b, c, d):
    print(a, b, c, d)

foo(*(1, 2), **{'d': 4, 'c': 3})      # Same as foo(1, 2, d=4, c=3)
# prints 1 2 3 4
foo(1, *(2, 3), **{'d': 4})           # Same as foo(1, 2, 3, d=4)
# prints 1 2 3 4
foo(1, c=3, *(2,), **{'d': 4})        # Same as foo(1, 2, c=3, d=4)
# prints 1 2 3 4
foo(1, *(2, 3), d=4)                  # Same as foo(1, 2, 3, d=4)
# prints 1 2 3 4
foo(1, *(2,), c=3, **{'d': 4})        # Same as foo(1, 2, c=3, d=4)
# prints 1 2 3 4

Python Keyword-Only Arguments

Keyword only arguments are the arguments that must be passed by keyword only.
Syntax with Example

def foo(a, *b, c):
    print(a, b, c)


def zoo(a, *, c):
    print(a, c)

Here c is a keyword only argument in both the functions, must be passed (as no default assigned) using key=value format

foo(5, 6, c=7)      # 5 (6,) 7
foo(a=5, c=7)       # 5 () 7
foo(5, *(6, ), c=7) # 5 (6,) 7
foo(5, 6, 7)        # TypeError: foo() missing 1 required keyword-only argument: 'c'
foo(5, *(6, ), 7)   # TypeError: foo() missing 1 required keyword-only argument: 'c'

zoo(5, c=6)         # 5, 6
zoo(5, 6)           # TypeError: zoo() takes 1 positional argument but 2 were given

So any argument after *b or * in these examples should be called by keyword (name=value format)
And the keyword only variables should present before the arbitrary keyword operator **kargs

def foo(a, *b, c, **d):
    print(a, b, c, d)

foo(1, 2, c=3, d=4) # prints 1 (2,) 3 {'d': 4}
foo(1, 2, 8, d=4)   # TypeError: foo() missing 1 required keyword-only argument: 'c'

c is a keyword-only argument

Click any Link
to navigate to certain page easily
Write a line to us
Your Email
Title
Description