Anik Sikder
Technical Writing/python/python-parameters-decoded-from-confusion-to-clarity
article.sh

$ open article

python

Python Parameters Decoded: From Confusion to Clarity

8 min readAugust 18, 2025
Python Function Parameters and Arguments Visualization

Hey Python developers! 👋

Have you ever wondered:

  • What's the difference between a parameter and an argument?

  • When should you use positional arguments versus keyword arguments?

  • What exactly are *args and **kwargs doing behind the scenes?

  • Why do mutable default arguments sometimes create bizarre bugs?

If so, you're in the right place.

Today we're diving deep into Python function parameters, one of the most important concepts in the language. Understanding how parameters work will help you write cleaner APIs, build more flexible functions, and avoid some of Python's most common mistakes.

Let's jump in. 🚀

Parameters vs Arguments: The First Confusion

One of the most common misunderstandings in Python comes from mixing up parameters and arguments.

Consider this example:

code
def make_pizza(size, topping):
    print(f"Making a {size}-inch pizza with {topping}.")

The variables size and topping are parameters.

Now let's call the function:

code
make_pizza(12, "pepperoni")

Here:

  • 12 and "pepperoni" are arguments

  • size and topping are parameters

Think of parameters as placeholders waiting for values, while arguments are the actual values provided when calling the function.

Positional vs Keyword Arguments

Python allows you to pass arguments in different ways.

Positional Arguments

With positional arguments, order matters.

code
make_pizza(16, "mushrooms")

Python assigns:

code
size = 16
topping = "mushrooms"

based purely on position.

Keyword Arguments

Keyword arguments explicitly specify which parameter receives which value.

code
make_pizza(
    topping="olives",
    size=14
)

Order no longer matters because names are provided.

Mixing Positional and Keyword Arguments

Python allows mixing both styles, but positional arguments must always come first.

code
make_pizza(
    12,
    topping="onions"
)

This works.

code
make_pizza(
    size=12,
    "onions"
)

This raises a syntax error.

Understanding Argument Unpacking

Unpacking allows Python to expand collections into individual arguments.

Think of it as opening a container and passing its contents directly into a function.

Iterable Unpacking with *

code
def greet(a, b, c):
    print(a, b, c)

values = [1, 2, 3]

greet(*values)

Python treats this as:

code
greet(1, 2, 3)

Dictionary Unpacking with **

code
def introduce(name, age):
    print(
        f"My name is {name}, I'm {age} years old."
    )

person = {
    "name": "Alice",
    "age": 25,
}

introduce(**person)

Python treats this as:

code
introduce(
    name="Alice",
    age=25
)

This becomes extremely useful when working with APIs, configuration objects, and dynamic function calls.

Meet *args: The Positional Collector

Sometimes you don't know how many positional arguments users will provide.

That's where *args comes in.

code
def party(
    organizer,
    *guests
):
    print(
        f"Organizer: {organizer}"
    )
    print(
        "Guests:",
        guests
    )

party(
    "Alice",
    "Bob",
    "Charlie",
    "Dana"
)

Output:

code
Organizer: Alice
Guests: (
    'Bob',
    'Charlie',
    'Dana'
)

Everything after the first required parameter gets packed into a tuple.

Think of *args as a collector that gathers any extra positional arguments.

Meet **kwargs: The Keyword Collector

While *args gathers positional arguments, **kwargs gathers keyword arguments.

code
def profile(
    name,
    **details
):
    print(f"Name: {name}")

    for key, value in details.items():
        print(
            f"{key}: {value}"
        )

profile(
    "Alice",
    age=25,
    city="London",
    hobby="chess"
)

Output:

code
Name: Alice
age: 25
city: London
hobby: chess

Everything beyond the explicitly defined parameters is collected into a dictionary.

This makes functions highly flexible and extensible.

Combining *args and **kwargs

You can combine both collectors in a single function.

code
def everything(
    required,
    *args,
    **kwargs
):
    print(
        "Required:",
        required
    )

    print(
        "Args:",
        args
    )

    print(
        "Kwargs:",
        kwargs
    )

everything(
    "Hello",
    1,
    2,
    3,
    a=10,
    b=20
)

Output:

code
Required: Hello

Args:
(1, 2, 3)

Kwargs:
{
    'a': 10,
    'b': 20
}

Parameter Order Rules

Python expects parameters in the following order:

  1. Standard parameters

  2. *args

  3. Keyword-only parameters

  4. **kwargs

Violating this order will raise syntax errors.

Extended Unpacking

Python also supports unpacking during assignment.

code
numbers = [
    1,
    2,
    3,
    4,
    5
]

a, *middle, b = numbers

print(a)
print(middle)
print(b)

Output:

code
1
[2, 3, 4]
5

This technique is incredibly useful when you need only specific parts of a sequence.

Default Parameters

Python allows parameters to have default values.

code
def greet(
    name,
    greeting="Hello"
):
    print(
        f"{greeting}, {name}"
    )

greet("Alice")
greet(
    "Bob",
    "Hi"
)

Output:

code
Hello, Alice
Hi, Bob

Default values make functions easier to use while still allowing customization.

The Mutable Default Argument Trap

One of Python's most famous pitfalls involves mutable defaults.

Consider:

code
def add_item(
    item,
    bucket=[]
):
    bucket.append(item)
    return bucket

Usage:

code
print(add_item(1))
print(add_item(2))

Output:

code
[1]
[1, 2]

Many developers expect:

code
[1]
[2]

But Python creates the default list only once, causing the same list to be reused across function calls.

The Correct Approach

code
def add_item(
    item,
    bucket=None
):
    if bucket is None:
        bucket = []

    bucket.append(item)

    return bucket

This ensures a new list is created each time.

Why *args and **kwargs Matter

You'll encounter these patterns everywhere:

  • Frameworks

  • Libraries

  • Decorators

  • API clients

  • Middleware systems

  • Django

  • FastAPI

  • Flask

Understanding them helps you build more reusable and flexible code.

Real-World Example

A common logging function might look like:

code
def log(
    message,
    *args,
    **kwargs
):
    print(message)

    if args:
        print(
            "Extra args:",
            args
        )

    if kwargs:
        print(
            "Metadata:",
            kwargs
        )

Usage:

code
log(
    "User login",
    123,
    source="google",
    plan="premium"
)

This flexibility is one reason Python APIs feel so expressive.

TL;DR Quick Recap

  • Parameters are variables defined in functions

  • Arguments are values passed during function calls

  • Positional arguments depend on order

  • Keyword arguments depend on names

  • *args collects extra positional arguments

  • **kwargs collects extra keyword arguments

  • Unpacking expands collections into arguments

  • Extended unpacking helps split sequences

  • Default parameters simplify function calls

  • Mutable defaults can create hidden bugs

Final Thoughts

Functions are one of Python's most powerful building blocks, and mastering parameters unlocks a new level of flexibility.

The next time you encounter *args, **kwargs, or complex function signatures, you'll know exactly what's happening behind the scenes.

And when someone complains about a mysterious function call, you can confidently say:

"Looks like a parameter problem." 😄


Frequently Asked Questions

What is the difference between parameters and arguments in Python?

Parameters are variables defined in a function signature.

Arguments are the actual values passed when calling the function.


What are positional arguments?

Positional arguments are assigned to parameters based on their order.

code
greet("Alice", 25)

What are keyword arguments?

Keyword arguments are assigned using parameter names.

code
greet(
    age=25,
    name="Alice"
)

What is *args in Python?

*args collects additional positional arguments into a tuple.

code
def func(*args):
    print(args)

What is **kwargs in Python?

**kwargs collects additional keyword arguments into a dictionary.

code
def func(**kwargs):
    print(kwargs)

What is argument unpacking?

Argument unpacking expands collections into individual arguments.

code
values = [1, 2, 3]

func(*values)

What is dictionary unpacking?

Dictionary unpacking expands key-value pairs into keyword arguments.

code
data = {
    "name": "Alice",
    "age": 25
}

func(**data)

Why are mutable default arguments dangerous?

Because they are created only once and reused across function calls.

This can lead to unexpected shared state.


What is the safest default value for mutable objects?

Use None.

code
def func(items=None):
    if items is None:
        items = []

Can a function use both *args and **kwargs?

Yes.

code
def func(
    *args,
    **kwargs
):
    pass

What is extended unpacking?

Extended unpacking allows one variable to capture multiple values.

code
a, *middle, b = data

When should I use keyword arguments?

Keyword arguments improve readability and reduce mistakes when functions have many parameters.


Why are *args and **kwargs common in frameworks?

They allow APIs to remain flexible and forward arguments dynamically.

Frameworks like Django, FastAPI, Flask, and Click use them extensively.


Are args and kwargs special keywords?

No.

Only the * and ** operators are special.

The names args and kwargs are conventions.


How do Python developers commonly use **kwargs?

Common use cases include:

  • Configuration objects

  • Dynamic APIs

  • Decorators

  • Framework internals

  • Optional settings


What should every Python developer know about function parameters?

Every Python developer should understand:

  • Parameters vs arguments

  • Positional arguments

  • Keyword arguments

  • Default values

  • Argument unpacking

  • *args

  • **kwargs

  • Mutable default pitfalls

These concepts form the foundation of effective Python programming.


Key Takeaways

  • Parameters define what a function expects.
  • Arguments provide actual values.
  • Positional arguments depend on order.
  • Keyword arguments depend on names.
  • *args gathers extra positional arguments.
  • **kwargs gathers extra keyword arguments.
  • Unpacking expands collections into arguments.
  • Mutable default parameters can cause subtle bugs.
  • Understanding parameter behavior is essential for writing flexible Python code.

If you found this helpful, share it with another Python developer and follow for more Python deep dives.


About the Author

Anik Sikder is a Software Engineer specializing in Backend Engineering, Python, Django, FastAPI, Cloud Infrastructure, SaaS Architecture, System Design, and scalable software engineering practices.

$ tags

pythonfunctionsparametersargumentsargskwargsunpackingpython-basics

$ ls related_articles

status: end_of_file