1. Advanced Argument Handling
While positional and keyword arguments are common, Python offers even more flexible ways to define function signatures.
Mutable Default Argument Pitfall:
A common mistake is using mutable objects (like lists or dictionaries) as default argument values. Default arguments are evaluated *only once* when the function is defined, not every time it's called.
def add_item_bad(item, item_list=[]): # DANGER! Default list created once.
item_list.append(item)
return item_list
print("--- Mutable Default Argument Pitfall ---")
list1 = add_item_bad("Apple")
print(f"List 1: {list1}") # Expected: ['Apple']
list2 = add_item_bad("Banana")
print(f"List 2: {list2}") # UNEXPECTED: ['Apple', 'Banana']!
list3 = add_item_bad("Orange", []) # Correct usage: provide new list
print(f"List 3: {list3}")
print("\n--- Correct Way to Handle Mutable Defaults ---")
def add_item_good(item, item_list=None): # Use None as default
if item_list is None: # Check if a list was NOT provided
item_list = [] # Create a new list ONLY if needed
item_list.append(item)
return item_list
list_a = add_item_good("Laptop")
print(f"List A: {list_a}")
list_b = add_item_good("Keyboard")
print(f"List B: {list_b}") # EXPECTED: ['Keyboard'] - no interaction with list_a
--- Mutable Default Argument Pitfall --- List 1: ['Apple'] List 2: ['Apple', 'Banana'] List 3: ['Orange'] --- Correct Way to Handle Mutable Defaults --- List A: ['Laptop'] List B: ['Keyboard']
Arbitrary Positional Arguments: `*args`
Sometimes you don't know in advance how many positional arguments a function will receive. The `*args` syntax allows a function to accept a variable number of non-keyword arguments. These arguments are then packed into a **tuple**.
def sum_all_numbers(*numbers):
"""Sums all numbers passed as positional arguments."""
total = 0
for num in numbers: # 'numbers' is a tuple
total += num
return total
print(f"Sum of (1, 2, 3): {sum_all_numbers(1, 2, 3)}")
print(f"Sum of (10, 20, 30, 40): {sum_all_numbers(10, 20, 30, 40)}")
print(f"Sum of (): {sum_all_numbers()}")
Sum of (1, 2, 3): 6 Sum of (10, 20, 30, 40): 100 Sum of (): 0
Arbitrary Keyword Arguments: `**kwargs`
If you need a function to accept a variable number of keyword arguments, use `**kwargs`. These arguments are packed into a **dictionary**, where keys are the argument names and values are their corresponding values.
def display_udaan_profile(**details):
"""Displays user profile details from keyword arguments."""
print("--- User Profile ---")
if not details:
print("No details provided.")
return
for key, value in details.items():
print(f"{key.replace('_', ' ').title()}: {value}")
display_udaan_profile(name="Alok Sharma", role="Data Scientist", experience_years=5)
print("")
display_udaan_profile(course="Python ML", batch="Summer 2025")
print("")
display_udaan_profile()
--- User Profile --- Name: Alok Sharma Role: Data Scientist Experience Years: 5 --- User Profile --- Course: Python ML Batch: Summer 2025 --- User Profile --- No details provided.
Argument Order in Function Definition:
When combining different types of arguments, Python has a strict order:
Positional-only -> Positional or Keyword -> `*args` -> Keyword-only -> `**kwargs`
def complex_function(a, b=10, *args, c, d=20, **kwargs):
print(f"a: {a}")
print(f"b (default): {b}")
print(f"args: {args}")
print(f"c (keyword-only): {c}")
print(f"d (keyword-only default): {d}")
print(f"kwargs: {kwargs}")
print("--- Calling complex_function ---")
complex_function(1, 2, 3, 4, c=5, e=6, f=7)
# a=1 (positional)
# b=2 (positional override default)
# *args=(3, 4)
# c=5 (keyword-only, MUST be keyword)
# d=20 (uses default)
# **kwargs={'e': 6, 'f': 7}
print("\n--- Another call ---")
complex_function(100, c=50, x="hello")
# a=100
# b=10 (uses default)
# *args=()
# c=50
# d=20 (uses default)
# **kwargs={'x': 'hello'}
--- Calling complex_function --- a: 1 b (default): 2 args: (3, 4) c (keyword-only): 5 d (keyword-only default): 20 kwargs: {'e': 6, 'f': 7} --- Another call --- a: 100 b (default): 10 args: () c (keyword-only): 50 d (keyword-only default): 20 kwargs: {'x': 'hello'}