In our journey through functions, we’ve encountered several types of parameters: standard positional parameters, parameters with default values (Post #89), the catch-all *args
(Post #101), and the catch-all **kwargs
(Post #102).
A natural question arises: “Can we use all of these in a single function?” The answer is yes! But Python is very strict about this. To avoid ambiguity, you must define them in a specific, non-negotiable order. In this post, we will learn the definitive order for all parameter types in a Python function signature.
The Golden Rule of Parameter Order
When you define a function that uses a combination of different parameter types, they must appear in the following sequence:
- Standard Positional Parameters (e.g.,
a
,b
) - Parameters with Default Values (e.g.,
c=None
,d=True
) - The
*args
Parameter (the catch-all for extra positional arguments) - The
**kwargs
Parameter (the catch-all for extra keyword arguments)
You don’t have to use all of them, but any that you do use must follow this order.
The “Kitchen Sink” Example
Let’s create a function that uses all four types in the correct order. We’ll call it the “kitchen sink” function because it includes a bit of everything!
def kitchen_sink_function(pos1, pos2, default1="hello", default2=None, *args, **kwargs):
"""A function that demonstrates the full parameter order."""
print("--- Function Call Results ---")
print(f"Standard Positional: pos1='{pos1}', pos2='{pos2}'")
print(f"Default Values: default1='{default1}', default2={default2}")
print(f"args (Tuple): {args}")
print(f"kwargs (Dictionary): {kwargs}")
This function signature tells Python: “Expect at least two positional arguments (pos1
, pos2
). The next two (default1
, default2
) have default values and are optional. Any other positional arguments should be collected into the args
tuple. Any keyword arguments that don’t match the named parameters should be collected into the kwargs
dictionary.”
Calling a Complex Function
Let’s see how Python distributes the arguments when we call this function in a few different ways.
Call 1: Only Required Arguments
Here, we only provide the two required positional arguments.
kitchen_sink_function('val1', 'val2')
Output:
--- Function Call Results ---
Standard Positional: pos1='val1', pos2='val2'
Default Values: default1='hello', default2=None
args (Tuple): ()
kwargs (Dictionary): {}
Call 2: Providing Extra Positional Arguments
Here, we provide enough arguments to fill the standard parameters, override the defaults, and have some left over for *args
.
kitchen_sink_function(1, 2, 3, 4, 5, 6)
Python maps them in order:
1
->pos1
2
->pos2
3
->default1
4
->default2
(5, 6)
-> collected intoargs
Output:
--- Function Call Results ---
Standard Positional: pos1='1', pos2='2'
Default Values: default1='3', default2=4
args (Tuple): (5, 6)
kwargs (Dictionary): {}
Call 3: The Full Monty
Now let’s provide arguments for everything.
kitchen_sink_function(1, 2, 3, 4, 5, 6, setting1='ON', setting2='OFF')
Python distributes them just as before, but this time the extra keyword arguments are collected into **kwargs
.
Output:
--- Function Call Results ---
Standard Positional: pos1='1', pos2='2'
Default Values: default1='3', default2=4
args (Tuple): (5, 6)
kwargs (Dictionary): {'setting1': 'ON', 'setting2': 'OFF'}
Incorrect Order Leads to an Error
This order is not just a convention; it’s a strict syntax rule. If you try to define a function with the parameters out of order, Python will raise a SyntaxError
before your code even runs.
# This will cause a SyntaxError!
# def invalid_function(pos1, default1="hello", *args, pos2):
# pass
You cannot have a regular parameter (pos2
) after the catch-all *args
.
What’s Next?
You now know the correct order for defining a function’s parameters: standard, then default, then *args
, then **kwargs
. While you’ll rarely write a function that uses all of them at once, understanding this hierarchy is essential for reading and writing complex functions in Python.
We’ve spent a lot of time learning the mechanics of defining and calling functions. Now, we’re going to step back and look at a profound and powerful concept in Python: what a function is. In Python, functions aren’t just blocks of code; they are objects, just like numbers and strings. In Post #104, we will explore what it means for functions to be first-class citizens.
Author

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com