0
0
Pythonprogramming~15 mins

Parameters and arguments in Python - Deep Dive

Choose your learning style9 modes available
Overview - Parameters and arguments
What is it?
Parameters and arguments are the way we send information into functions in Python. Parameters are the names listed in a function’s definition, like placeholders. Arguments are the actual values you give to those placeholders when you call the function. This lets functions work with different data each time you use them.
Why it matters
Without parameters and arguments, functions would always do the same thing and could not handle different inputs. This would make programs rigid and repetitive. Parameters and arguments let us write flexible, reusable code that adapts to many situations, saving time and reducing mistakes.
Where it fits
Before learning parameters and arguments, you should understand what functions are and how to define and call them. After this, you can learn about advanced function features like default values, keyword arguments, and variable-length arguments.
Mental Model
Core Idea
Parameters are the function’s named placeholders, and arguments are the real values you plug into those placeholders when calling the function.
Think of it like...
Think of a function like a cookie cutter (the function definition) with empty spaces (parameters) where you press dough (arguments) to shape cookies. The cutter defines the shape, but the dough you use changes each cookie.
Function definition: def greet(name):
                      ↑
                 parameter

Function call: greet('Alice')
               ↑
             argument
Build-Up - 7 Steps
1
FoundationUnderstanding function parameters
🤔
Concept: Parameters are the names used inside a function to refer to the inputs it expects.
When you write a function, you put names inside the parentheses to show what information the function needs. These names are called parameters. For example: def say_hello(name): print('Hello, ' + name) Here, 'name' is a parameter. It is like a label for the input the function will use.
Result
The function knows it needs one piece of information called 'name' to work.
Understanding parameters helps you see how functions get the data they need to do their job.
2
FoundationCalling functions with arguments
🤔
Concept: Arguments are the actual values you give to a function’s parameters when you call it.
When you use a function, you provide real values called arguments. These fill the parameters. For example: say_hello('Alice') Here, 'Alice' is the argument. It replaces the parameter 'name' inside the function.
Result
The function prints: Hello, Alice
Knowing arguments lets you control what data a function works with each time you call it.
3
IntermediatePositional vs keyword arguments
🤔Before reading on: Do you think the order of arguments matters when calling a function? Commit to your answer.
Concept: Arguments can be passed by position or by naming the parameter explicitly (keyword).
Positional arguments are matched to parameters by order: def describe_pet(animal, name): print(animal + ': ' + name) describe_pet('dog', 'Buddy') # 'dog' → animal, 'Buddy' → name Keyword arguments use parameter names: describe_pet(name='Buddy', animal='dog') This lets you change the order and improve clarity.
Result
Both calls print: dog: Buddy
Understanding argument types helps avoid bugs and makes code easier to read and maintain.
4
IntermediateDefault parameter values
🤔Before reading on: If a function has a default value for a parameter, do you think you must always provide an argument for it? Commit to your answer.
Concept: Parameters can have default values used when no argument is given.
You can set a default value for a parameter like this: def greet(name='friend'): print('Hello, ' + name) Calling greet() uses 'friend' automatically: greet() # prints Hello, friend greet('Alice') # prints Hello, Alice
Result
The function works even if you skip the argument, using the default.
Default values make functions flexible and reduce the need to always specify every argument.
5
IntermediateVariable-length arguments
🤔Before reading on: Can a function accept any number of arguments without knowing how many in advance? Commit to your answer.
Concept: Functions can accept any number of arguments using special syntax *args and **kwargs.
Use *args to collect extra positional arguments as a tuple: def add_all(*numbers): total = 0 for num in numbers: total += num print(total) add_all(1, 2, 3) # prints 6 Use **kwargs to collect extra keyword arguments as a dictionary: def print_info(**info): for key, value in info.items(): print(key + ': ' + str(value)) print_info(name='Alice', age=30)
Result
Functions can handle flexible numbers of inputs.
Variable-length arguments let you write very general functions that adapt to many situations.
6
AdvancedParameter passing and mutability
🤔Before reading on: When you pass a list to a function and change it inside, does the original list outside also change? Commit to your answer.
Concept: Understanding how Python passes arguments (by object reference) and how mutable objects behave inside functions.
Python passes references to objects, not copies. If you pass a mutable object like a list: def add_item(lst): lst.append(4) my_list = [1, 2, 3] add_item(my_list) print(my_list) # prints [1, 2, 3, 4] The original list changes because both names point to the same object. Immutable objects like numbers or strings do not change outside the function.
Result
Changes to mutable arguments inside functions affect the original object.
Knowing this prevents bugs where data changes unexpectedly and helps decide when to copy data.
7
ExpertParameter annotations and introspection
🤔Before reading on: Do parameter names and types affect how Python runs the function? Commit to your answer.
Concept: Python allows adding optional type hints (annotations) to parameters and lets you inspect them at runtime.
You can write: def greet(name: str, age: int) -> None: print(f'Hello {name}, you are {age}') These annotations do not change how the function runs but help tools and readers understand expected types. You can access annotations with: print(greet.__annotations__) which shows {'name': , 'age': , 'return': None}
Result
Annotations improve code clarity and enable advanced tools like type checkers.
Understanding annotations and introspection unlocks better documentation, debugging, and static analysis.
Under the Hood
When a function is called, Python creates a new local space where parameter names are assigned to the argument objects passed. This binding links the parameter names to the actual data. Python uses references to objects, so parameters point to the same objects as arguments. Mutable objects can be changed through these references, while immutable objects cannot. Default values are stored once when the function is defined, which can lead to subtle bugs if mutable defaults are used.
Why designed this way?
Python’s design favors simplicity and flexibility. Passing references avoids copying large data, improving performance. Default parameters provide convenience but require care to avoid shared mutable defaults. Annotations were added later to support optional typing without breaking existing code, keeping Python dynamically typed but more robust with tools.
Function call flow:

Caller code
   │
   ▼
Function call with arguments
   │
   ▼
Python creates local frame
   │
   ├─ Parameters assigned to argument objects
   │
   ├─ Default values used if no argument
   │
   ▼
Function body runs using parameters
   │
   ▼
Return value sent back to caller
Myth Busters - 4 Common Misconceptions
Quick: Does changing a parameter inside a function always change the original argument outside? Commit yes or no.
Common Belief:Changing a parameter inside a function always changes the original argument outside.
Tap to reveal reality
Reality:Only mutable objects like lists or dictionaries can be changed inside a function to affect the original. Immutable objects like numbers or strings cannot be changed this way.
Why it matters:Assuming all changes affect the original can cause confusion and bugs when data does not update as expected.
Quick: Do you think default parameter values are re-created each time the function runs? Commit yes or no.
Common Belief:Default parameter values are created fresh every time the function is called.
Tap to reveal reality
Reality:Default parameter values are created once when the function is defined, not each call. If the default is mutable, changes persist across calls.
Why it matters:This can cause unexpected behavior, like a list growing every time the function is called without an argument.
Quick: Can you pass arguments to a function in any order if you use positional arguments only? Commit yes or no.
Common Belief:You can pass positional arguments in any order to a function.
Tap to reveal reality
Reality:Positional arguments must be in the exact order of parameters. Only keyword arguments can be passed in any order.
Why it matters:Mixing up argument order leads to wrong data being used, causing bugs that are hard to spot.
Quick: Do parameter annotations affect how Python runs the function? Commit yes or no.
Common Belief:Parameter annotations change how Python executes the function and enforce types.
Tap to reveal reality
Reality:Annotations are only hints and do not affect runtime behavior or enforce types by themselves.
Why it matters:Expecting annotations to enforce types can lead to false confidence and missed errors.
Expert Zone
1
Default parameter values are evaluated once at function definition, so mutable defaults can cause shared state across calls.
2
Using *args and **kwargs allows writing flexible APIs but can make debugging harder if overused or unclear.
3
Parameter names are part of a function’s signature and affect introspection, decorators, and some metaprogramming techniques.
When NOT to use
Avoid using mutable default parameters to prevent shared state bugs; instead, use None and assign inside the function. For very strict type enforcement, use external tools like mypy rather than relying on annotations alone. When performance is critical, avoid excessive use of *args/**kwargs as they add overhead.
Production Patterns
In real-world code, functions often combine positional, keyword, and default parameters for clarity and flexibility. APIs use keyword-only parameters to force explicit naming. Annotations are used with static type checkers to catch bugs early. Variable-length arguments enable decorators and wrappers that handle unknown inputs.
Connections
Function decorators
Builds-on parameters and arguments by wrapping functions and modifying inputs or outputs.
Understanding parameters and arguments is essential to grasp how decorators intercept and manipulate function calls.
API design
Parameters and arguments define how users interact with functions or services.
Good parameter design improves usability and reduces errors in software interfaces.
Linguistics - Grammar and Syntax
Parameters and arguments relate like sentence structure: parameters are like sentence slots, arguments are the words filling them.
Recognizing this connection helps understand how meaning changes with different inputs, similar to how sentence meaning changes with word order and choice.
Common Pitfalls
#1Using a mutable object as a default parameter causes unexpected shared state.
Wrong approach:def add_item(item, lst=[]): lst.append(item) return lst print(add_item(1)) # [1] print(add_item(2)) # [1, 2] (unexpected!)
Correct approach:def add_item(item, lst=None): if lst is None: lst = [] lst.append(item) return lst print(add_item(1)) # [1] print(add_item(2)) # [2]
Root cause:Default parameters are evaluated once, so the same list is reused across calls.
#2Passing arguments in wrong order causes wrong data to be used.
Wrong approach:def describe_pet(animal, name): print(animal + ': ' + name) describe_pet('Buddy', 'dog') # wrong order
Correct approach:describe_pet('dog', 'Buddy') # correct order # or use keyword arguments: describe_pet(name='Buddy', animal='dog')
Root cause:Positional arguments must match parameter order; mixing them up swaps data.
#3Expecting parameter annotations to enforce types at runtime.
Wrong approach:def greet(name: str): print(name.upper()) greet(123) # no error, but unexpected
Correct approach:# Use a type checker like mypy to catch errors before running # or add manual checks inside the function if not isinstance(name, str): raise TypeError('name must be a string')
Root cause:Annotations are hints only; Python does not enforce types automatically.
Key Takeaways
Parameters are named placeholders in function definitions; arguments are the actual values passed when calling functions.
Positional arguments must follow the order of parameters, while keyword arguments can be passed in any order for clarity.
Default parameter values provide flexibility but beware of mutable defaults causing shared state bugs.
Python passes references to objects, so mutable arguments can be changed inside functions affecting the original data.
Parameter annotations improve code readability and tooling but do not enforce types at runtime.