Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Python Function Parameters: Types, Usage, and Best Practices

Tech May 8 4

Two Categories of Function Parameters

Formal Parameters

Formal parameters (形参) are the variable names defined in the function's parentheses during the definition phase.

def calculate(a, b):
    pass

# a and b are formal parameters

Actual Arguments

Actual arguments (实参) are the values passed into the function's parentheses during the call phase.

def calculate(a, b):
    return a + b

calculate(5, 10)
# 5 and 10 are actual arguments

Relationship Between Formal and Actual Arguments

The binding between formal and actual parameters occurs at call time and breaks when the function exits. Formal parameters only receive variable names, while actual arguments can be values, variable names, or function return values—essentially anything that evaluates to a value.

Positional Parameters

Positional parameters are defined in order from left to right in the function's parameter list.

Positional Formal Parameters

Variables defined in order during function definition are positional formal parameters.

def compare(x, y, z):
    pass

# x, y, z are positional formal parameters

Positional Actual Arguments

Values passed in order during function call are positional actual arguments.

compare(100, 50, 200)
# 100, 50, 200 are positional actual arguments

Key characteristic: Positional parameters require a one-to-one correspondence between formal and actual arguments.

def find_maximum(first, second):
    return first if first > second else second

# Correct usage
result = find_maximum(30, 15)

# Incorrect - wrong number of arguments
# find_maximum(10, 20, 30)  # Too many arguments
# find_maximum(10)         # Too few arguments

Keyword Arguments

Keyword arguments allow passing values by explicitly naming parameters, bypassing positional order.

result = find_maximum(second=25, first=100)

Important rule: Positional arguments must appear before keyword arguments. The following is invalid:

# Invalid syntax
# result = find_maximum(second=10, 20)

# Valid syntax
result = find_maximum(20, second=10)

Default Parameters

Default parameters have predefined values assigned during function definition.

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}"

print(greet("Alice"))           # Uses default: "Hello, Alice"
print(greet("Bob", "Hi"))      # Uses provided: "Hi, Bob"

Default Parameter Pitfall with Mutable Objects

When a default parameter is a mutable object (like a list or dictionary), all calls share the same object:

def add_skill(name, skills=[]):
    skills.append(name)
    print(skills)

add_skill("Python")      # Output: ['Python']
add_skill("JavaScript")  # Output: ['Python', 'JavaScript']
add_skill("Go")          # Output: ['Python', 'JavaScript', 'Go']

The correct approach uses None as a sentinel value:

def add_skill(name, skills=None):
    if skills is None:
        skills = []
    skills.append(name)
    print(skills)

Default Values Are Fixed at Definition Time

Default values are evaluated once when the function is defined, not at call time:

limit = 100
def validate(value, threshold=limit):
    print(value, threshold)

limit = 200
validate(50)  # Output: 50 100

Variable-Length Arguments

Collecting Excess Positional Arguments with *args

The * operator captures any extra positional arguments into a tuple:

def sum_all(x, y, *remaining):
    total = x + y
    for num in remaining:
        total += num
    return total

result = sum_all(1, 2, 3, 4, 5, 6)
# x=1, y=2, remaining=(3, 4, 5, 6), returns 21

Collecting Excess Keyword Arguments with **kwargs

The ** operator captures extra keyword arguments into a dictionary:

def display_config(name, **options):
    print(f"Name: {name}")
    print(f"Options: {options}")

display_config("Server", port=8080, debug=True, timeout=30)
# Name: Server
# Options: {'port': 8080, 'debug': True, 'timeout': 30}

By convention, *args and **kwargs are the standard names, where args stands for arguments and kwargs for keyword arguments.

Using * and ** in Actual Arguments

When calling functions, ** unpacks dictionaries into keyword arguments:

def create_user(username, email, age, role):
    print(f"User: {username}, Email: {email}, Age: {age}, Role: {role}")

config = {"username": "admin", "email": "admin@example.com", 
          "age": 30, "role": "superuser"}

create_user(**config)

Similarly, * can unpack iterables into positional arguments.

Combining All Parameter Types

A function can accept various parameter types in this order:

def process(a, b, c=10, *args, **kwargs):
    print(f"Required: a={a}, b={b}")
    print(f"Default: c={c}")
    print(f"Extra positional: {args}")
    print(f"Extra keyword: {kwargs}")

process(1, 2, 3, 4, 5, mode="fast", debug=True)
# Required: a=1, b=2
# Default: c=3
# Extra positional: (4, 5)
# Extra keyword: {'mode': 'fast', 'debug': True}

Keyword-Only Parameters

Parameters appearing after a bare * must be passed as keyword arguments only:

def send_notification(to, subject, *, urgent=False, high_priority=False):
    print(f"To: {to}, Subject: {subject}")
    print(f"Urgent: {urgent}, High Priority: {high_priority}")

# Valid calls
send_notification("user@example.com", "Meeting reminder")
send_notification("user@example.com", "Alert!", urgent=True)

# Invalid - positional passing for keyword-only params
# send_notification("user@example.com", "Alert!", True)  # TypeError

This syntax forces explicit parameter names, making code more readable and preventing accidental positional argument mistakes, particularly useful in large codebases and APIs.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.