sec03 - Python Function Arguments Explained: Default, Keyword, and Variable-Length Parameters
スポンサーリンク

1. Basics of Arguments

Functions can receive arguments. An argument is the data passed to a function, allowing the same function to be reused with different values. On the function definition side, these values are received as parameters, while the caller provides the actual values.

💡 Example Code

def greet(name):
    print(f'Hello, {name}!')

greet('Alice')

🖥️ Output

Hello, Alice!

In this code, the greet function accepts a parameter name and prints it as part of a string.
Calling greet("Alice") assigns "Alice" to name. Changing the argument allows the same function to be reused multiple times.

💡 Example Code 2: Reusing the same function

greet('John')
greet('Smith')

🖥️ Output

Hello, John!
Hello, Smith!

By changing the argument, you can call the same function with different data. This makes functions versatile and reusable tools.

2. Multiple Arguments (Positional Arguments)

2-1. Basics of Multiple Positional Arguments

You can pass multiple arguments to a function by separating them with commas ,.

Arguments are assigned to parameters in the order they are defined. This type of argument is called a positional argument. Changing the order can change the result.

💡 Example Code 1: Receiving multiple arguments

def add(a, b):
    print(a + b)

add(3, 5)

🖥️ Output

8

The add function takes two parameters, a and b.
Calling add(3, 5) assigns a=3 and b=5, then prints their sum.

💡 Example Code 2: Order matters

def divide(dividend, divisor):
    print(dividend / divisor)

divide(10, 2)
divide(2, 10)

🖥️ Output

5.0
0.2

Positional arguments are order-sensitive. Swapping the values for dividend and divisor changes the result. Pay attention to the order when calling functions.

2-2. Notes on Positional Arguments

When a function expects positional arguments, the caller must provide the exact number required. Too few or too many arguments will cause an error.

スポンサーリンク

3. Keyword Arguments

Using keyword arguments, you can assign values by parameter name. This improves readability and removes order dependency.

💡 Example Code 1: Keyword arguments

def divide(dividend, divisor):
    print(dividend / divisor)

divide(divisor=2, dividend=10)
divide(dividend=10, divisor=2)

🖥️ Output

5.0
5.0

Keyword arguments fix the assignment, so changing the order does not affect the result.

4. Default Arguments

4-1. Basics of Default Arguments

Setting default values for parameters allows you to omit them when calling a function. If omitted, the default value is used automatically.

💡 Example Code 1: Single default value

def greet(name='Guest'):
    print(f'Welcome, {name}!')

greet()
greet('John')
greet(name='Mary')

🖥️ Output

Welcome, Guest!
Welcome, John!
Welcome, Mary!

Default values are only used if the argument is omitted.
greet() uses "Guest", while greet('John') uses the provided value "John".

There are three main ways to pass arguments to functions with default values:

  • Omit the argument (default value is used)
  • Pass only the value as a positional argument
  • Pass the argument as a keyword, e.g., name='Mary'

💡 Example Code 2: Multiple default values

def connect(host='localhost', port=8080):
    print(f'Connecting to {host}:{port}')

connect()
connect('example.com', 3000)
connect('example.com')
connect(port=3000)
connect(host='example.com')
connect(host='example.com', port=3000)

🖥️ Output

Connecting to localhost:8080
Connecting to example.com:3000
Connecting to example.com:8080
Connecting to localhost:3000
Connecting to example.com:8080
Connecting to example.com:3000

Notes when calling functions with multiple default values:

  • [Line 5] Passing arguments like ('example.com', 3000) assigns values in the order they are defined.
  • [Line 6] Passing ('example.com') assigns host='example.com' and uses the default port=8080.
  • [Line 7] To pass only port, use a keyword argument: port=3000. Writing connect(3000) would assign 3000 to host instead.
  • [Line 8] You can use host='example.com' as a keyword argument.
  • [Line 9] Using keywords for all arguments is also fine (host='example.com', port=3000).

4-2. Mutable Default Argument Issue

💡 Example Code 3: Mutable default value issue

def add_item(item, item_list=[]):
    item_list.append(item)
    print(item_list)

add_item('A')
add_item('B')

🖥️ Output

['A']
['A', 'B']

Using a list as a default value reuses the same list created at function definition. This can unintentionally accumulate elements. This issue applies to other mutable data structures as well.

A safe approach is to set the default to None and create a new list inside the function if no argument is provided.

In the following code, if item_list is None (no list passed), a new list is created inside the function. This prevents reusing the same list. If a list is provided, the function adds the item to that list.

def add_item_safe(item, item_list=None):
    if item_list is None:
        item_list = []  # Create a new list if no argument is passed
    item_list.append(item)
    print(item_list)

add_item_safe('A')
add_item_safe('B')
add_item_safe('C', ['Provided list'])

🖥️ Output

['A']
['B']
['Provided list', 'C']

5. Variable-Length Arguments *args

Using an asterisk * before a parameter name, like *args, allows a function to accept any number of positional arguments.

💡 Example Code

def add_all(*numbers):
    print(f'numbers = {numbers}')
    print(f'Sum of arguments = {sum(numbers)}')

add_all()
add_all(100)
add_all(1, 2, 3)
add_all(5, 10, 15, 20)

🖥️ Output

numbers = ()
Sum of arguments = 0
numbers = (100,)
Sum of arguments = 100
numbers = (1, 2, 3)
Sum of arguments = 6
numbers = (5, 10, 15, 20)
Sum of arguments = 50

Values received via *args are grouped into a tuple, so any number of arguments (including zero) can be handled. Write function code assuming the values come as a tuple.

6. Variable-Length Keyword Arguments **kwargs

Using two asterisks ** before a parameter name, like **kwargs, allows a function to accept any number of keyword arguments.

💡 Example Code

def show_info(**info):
    print(info)

show_info(name='Alice', age=25)
show_info(job='Engineer', country='Japan')

🖥️ Output

{'name': 'Alice', 'age': 25}
{'job': 'Engineer', 'country': 'Japan'}

Values received via **kwargs are grouped into a dict, allowing any keyword arguments to be passed freely.

7. Mutable vs Immutable

Mutable objects like lists or dicts can be modified inside a function, affecting the caller. Immutable objects like numbers or strings are not affected.

💡 Example Code 1: Mutable

def add_element(lst):
    lst.append(4)
    print(f'lst = {lst}')

my_list = [1, 2, 3]
add_element(my_list)
print(f'my_list = {my_list}')

🖥️ Output

lst = [1, 2, 3, 4]
my_list = [1, 2, 3, 4]

The caller's list (my_list) is modified inside the function, and the changes persist.

💡 Example Code 2: Immutable

def add_one(n):
    n += 1
    print(f'n = {n}')

x = 10
add_one(x)
print(f'x = {x}')

🖥️ Output

n = 11
x = 10

Numbers are immutable, so changes to n inside the function do not affect the caller's x.

8. Argument Order Rules

Python functions have a strict order for different types of arguments. Violating this order causes errors.

def func(a=1, b):
    pass

🖥️ Output

SyntaxError: parameter without a default follows parameter with a default

You cannot place a parameter without a default value after one that has a default.

9. Argument Unpacking

You can unpack lists or dicts into arguments.

To unpack a list into positional arguments, prefix it with an asterisk *.

def add(a, b, c):
    print(a + b + c)

numbers = [1, 2, 3]
add(*numbers)
6

Conceptually, add(*[1, 2, 3]) becomes add(1, 2, 3).

To unpack a dict into keyword arguments, prefix it with double asterisks **.

def greet(name, age):
    print(f'{name} is {age} years old.')

person = {'name': 'Alice', 'age': 25}
greet(**person)
Alice is 25 years old.

Conceptually, greet(**{'name': 'Alice', 'age': 25}) becomes greet(name='Alice', age=25).

10. Combining Argument Types

def introduce(name, age=18, *hobbies, **profile):
    print('Name:', name)
    print('Age:', age)
    print('Hobbies:', hobbies)
    print('Profile:', profile)

introduce('Alice', 25, 'Reading', 'Travel', country='Japan', job='Engineer')
Name: Alice
Age: 25
Hobbies: ('Reading', 'Travel')
Profile: {'country': 'Japan', 'job': 'Engineer'}
  • Positional argument name: first value "Alice" goes to name.
  • Default argument age: value 25 overrides default 18.
  • *args hobbies: remaining positional arguments "Reading" and "Travel" are grouped into a tuple.
  • **kwargs profile: remaining keyword arguments country='Japan' and job='Engineer' are grouped into a dict.

Argument assignment order is: positional → default → *args → **kwargs.

スポンサーリンク