Python Functions: Complete Guide to def, Return Values, *args & **kwargs

In software engineering, repeating identical code across multiple files causes bugs and maintenance nightmares. The DRY principle (Don't Repeat Yourself) is realized through functions. A function modularizes your program into smaller, testable units, avoids repetition, and makes complex applications manageable.


1. Defining and Calling a Function: def and return

Functions are declared using the def keyword, followed by the function identifier, parentheses (), and a colon ::

# Defining a function with parameters and type hints:
def calculate_cylinder_volume(radius: float, height: float) -> float:
    """Calculates and returns the volume of a cylinder: V = pi * r^2 * h"""
    pi = 3.14159265359
    volume = pi * (radius ** 2) * height
    return volume

# Calling the function and capturing returned value:
result = calculate_cylinder_volume(5.0, 10.0)
print(f"Cylinder Volume: {result:.2f} cubic units")
# Output: Cylinder Volume: 785.40 cubic units

2. Function Parameters: Positional, Keyword & Default Arguments

Python provides exceptional flexibility when passing arguments:

def create_user(username, email, role="Subscriber", is_active=True):
    return {
        "username": username,
        "email": email,
        "role": role,
        "active": is_active
    }

# 1. Positional Arguments:
u1 = create_user("rahul_sharma", "rahul@example.com")

# 2. Keyword Arguments (order does not matter!):
u2 = create_user(email="priya@domain.com", username="priya_k", role="Admin")

print("User 1:", u1)
print("User 2:", u2)

Crucial Python Rule (BCA Exam Alert): Non-default arguments cannot follow default arguments! def test(a=10, b): causes a SyntaxError: non-default argument follows default argument.


3. Variable-Length Arguments: *args and **kwargs

When you do not know in advance how many arguments a user might pass, use *args (tuple packing) and **kwargs (dictionary packing):

# 1. *args (Variable positional arguments packed as tuple):
def calculate_sum(*numbers):
    total = sum(numbers)
    print(f"Adding {len(numbers)} numbers: Sum = {total}")
    return total

calculate_sum(10, 20, 30, 40)   # 100
calculate_sum(5, 15)             # 20

# 2. **kwargs (Variable keyword arguments packed as dict):
def print_student_profile(**details):
    print("--- Student Profile ---")
    for key, value in details.items():
        print(f"{key.capitalize()}: {value}")

print_student_profile(name="Ankit", college="Delhi University", course="BCA", gpa=9.2)

4. Returning Multiple Values via Tuple Packing

Python functions can return multiple values simultaneously in a single line:

def get_min_max_avg(numbers_list):
    return min(numbers_list), max(numbers_list), sum(numbers_list) / len(numbers_list)

minimum, maximum, average = get_min_max_avg([45, 90, 78, 62, 88])
print(f"Min: {minimum}, Max: {maximum}, Avg: {average:.1f}")

Frequently Asked Questions (FAQ)

Why is using a mutable object (like a list) as a default parameter dangerous?

In Python, default arguments are evaluated only once when the function is defined, not every time it is called. If you write def append_item(x, lst=[]), the same list object is reused across all subsequent calls! The Pythonic solution is: def append_item(x, lst=None): if lst is None: lst = [].
Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!