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'
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.
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)
)
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.
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
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.
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
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