Default Arguments

basic
Published

June 1, 2024

Understanding Default Arguments

A default argument is a value provided in the function definition that’s automatically used if the caller doesn’t supply a corresponding argument during the function call. This simplifies function calls and enhances code reusability.

Let’s illustrate with a simple example:

def greet(name, greeting="Hello"):
  """Greets a person with a customizable greeting."""
  print(f"{greeting}, {name}!")

greet("Alice")  # Output: Hello, Alice!
greet("Bob", "Good morning")  # Output: Good morning, Bob!

In this example, greeting has a default value of “Hello”. If you call greet() without specifying a greeting, it defaults to “Hello”. However, you can override this default by providing a different greeting during the function call.

Benefits of Using Default Arguments

  • Reduced Code Verbosity: Default arguments reduce the need for multiple function overloads or conditional statements within the function body to handle different input scenarios.

  • Improved Readability: Code becomes cleaner and easier to understand when default values are explicitly defined. The intent of the function is clearer.

  • Enhanced Flexibility: Default arguments allow for greater flexibility in how the function is used, catering to various situations without requiring major code changes.

Potential Pitfalls and Best Practices

While incredibly useful, default arguments can lead to unexpected behavior if not handled carefully. The most common issue stems from mutable default arguments.

Mutable Default Arguments (A common mistake):

Avoid using mutable objects (like lists and dictionaries) as default arguments directly. This is because the default argument is created once when the function is defined, not each time it’s called.

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

print(add_item(1))  # Output: [1]
print(add_item(2))  # Output: [1, 2]  Unexpected!

Notice how the second call to add_item modifies the same list used in the first call. This is because my_list is initialized only once.

The Solution: Use None as the default and create the mutable object inside the function:

def add_item(item, my_list=None):
  if my_list is None:
    my_list = []
  my_list.append(item)
  return my_list

print(add_item(1))  # Output: [1]
print(add_item(2))  # Output: [2]  Now correct!

This ensures that a new list is created for each function call, preventing unintended side effects.

Ordering of Arguments

Remember that default arguments must always come after non-default arguments in the function definition. This is a syntactical rule in Python.

def example(a, b=2, c=3): #Correct
    print(a,b,c)

def example2(a=1, b, c): #Incorrect - will raise a SyntaxError
    print(a,b,c)