Python Parameters Decoded: From Confusion to Clarity
Anik Sikder

Anik Sikder @anik_sikder_313

About: Full-Stack Dev & Tech Writer | Python (Django, FastAPI), JS (React, Next.js) | I build fast, scalable apps & write on backend, frontend, APIs & Web3 | Open to freelance/remote roles

Location:
Dhaka, Bangladesh
Joined:
Aug 6, 2025

Python Parameters Decoded: From Confusion to Clarity

Publish Date: Aug 18
2 1

(aka: The Art of Talking With Your Functions Without Losing Your Mind)

Functions are like little wizards in Python. You hand them some ingredients, they stir their magical cauldron, and-poof-you get a result. But here’s the catch: if you don’t know how to hand over those ingredients correctly, your wizard might either mess up the potion or throw a TypeError tantrum.

So today, we’re going on a deep dive into function parameters: arguments vs parameters, positional vs keyword arguments, the mysteries of *args and **kwargs, unpacking secrets, and the sneaky pitfalls of default parameters. By the end, you’ll not only understand them, you’ll be able to explain them like an absolute genius.


Arguments vs Parameters, The First Misunderstanding

Let’s clear this up before we go too far:

  • Parameters are the names you define in the function.
  • Arguments are the actual values you pass when you call the function.

Think of it like this:

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

make_pizza(12, "pepperoni")  # arguments
Enter fullscreen mode Exit fullscreen mode

👉 Parameters = variables waiting for data.
👉 Arguments = the data you actually send.

Simple, but critical.


Positional vs Keyword Arguments

Python lets you call functions in two ways:

  1. Positional arguments order matters:
   make_pizza(16, "mushrooms")  # size=16, topping="mushrooms"
Enter fullscreen mode Exit fullscreen mode
  1. Keyword arguments order doesn’t matter:
   make_pizza(topping="olives", size=14)  
Enter fullscreen mode Exit fullscreen mode

If you mix them, positional always goes first. Otherwise, Python gets confused:

make_pizza(12, topping="onions")  # ✅ fine
make_pizza(size=12, "onions")     # ❌ SyntaxError
Enter fullscreen mode Exit fullscreen mode

The Magic of Unpacking

Unpacking is like giving Python a backpack of values and saying: “Here, open this and figure it out.”

Iterable unpacking with *:

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

values = [1, 2, 3]
greet(*values)  # same as greet(1, 2, 3)
Enter fullscreen mode Exit fullscreen mode

Dictionary unpacking with **:

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

person = {"name": "Alice", "age": 25}
introduce(**person)  # same as introduce(name="Alice", age=25)
Enter fullscreen mode Exit fullscreen mode

This is insanely powerful when you don’t know ahead of time how many values you’ll deal with.


Enter *args The Collector of Extras

Sometimes you don’t know how many arguments someone will pass. That’s where *args comes in.

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

party("Alice", "Bob", "Charlie", "Dana")
Enter fullscreen mode Exit fullscreen mode

Output:

Organizer: Alice
Guests: ('Bob', 'Charlie', 'Dana')
Enter fullscreen mode Exit fullscreen mode

Notice that *args packs all extra positional arguments into a tuple.
Think of it as: “whatever’s left over, put it in a bag.”


Enter **kwargs The Dictionary of Chaos

And then comes the sibling: **kwargs.
It gathers all extra keyword arguments into a dictionary.

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")
Enter fullscreen mode Exit fullscreen mode

Output:

Name: Alice
age: 25
city: London
hobby: chess
Enter fullscreen mode Exit fullscreen mode

Boom! Suddenly, your function is infinitely flexible.


Combining *args and **kwargs

The ultimate weapon:

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

everything("Hello", 1, 2, 3, a=10, b=20)
Enter fullscreen mode Exit fullscreen mode

Output:

Required: Hello
Args: (1, 2, 3)
Kwargs: {'a': 10, 'b': 20}
Enter fullscreen mode Exit fullscreen mode

Golden rule of parameter order:

  1. Normal parameters
  2. *args
  3. Keyword-only parameters
  4. **kwargs

If you mess this up, Python will shout at you.


Extended Unpacking, Next-Level Wizardry

Python even lets you “spread” collections inside assignments:

numbers = [1, 2, 3, 4, 5]
a, *middle, b = numbers
print(a)       # 1
print(middle)  # [2, 3, 4]
print(b)       # 5
Enter fullscreen mode Exit fullscreen mode

This is brilliant for when you need the “edges” of a list but don’t care about the middle (or vice versa).


Parameter Defaults, Beware of Mutables!

Here’s a classic Python “gotcha”:

def add_item(item, bucket=[]):  # 🚨 Danger!
    bucket.append(item)
    return bucket

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2]  <-- surprise!
Enter fullscreen mode Exit fullscreen mode

Why? Because the default list is created once, not each time. So it keeps growing.
The safe way:

def add_item(item, bucket=None):
    if bucket is None:
        bucket = []
    bucket.append(item)
    return bucket
Enter fullscreen mode Exit fullscreen mode

Always be careful with mutable default arguments (lists, dicts, sets).


Putting It All Together

You now have the full toolkit:

  • Parameters vs arguments ✅
  • Positional & keyword arguments ✅
  • Unpacking iterables and dictionaries ✅
  • *args and **kwargs mastery ✅
  • Extended unpacking ✅
  • Default parameter pitfalls ✅

With these in your arsenal, you’re no longer just “using functions” you’re wielding them like a sorcerer.

The next time someone complains about messy function calls, you can smile, sip your coffee, and whisper: “Have you tried *args and `kwargs`?”

Comments 1 total

Add comment