Syntax
def function_name(parameters):
# function body
return valueExamples
A small working example
Follow the values through this example, then change one input.
def total(price, quantity):
return price * quantity
print(total(12, 3))Basic Functions
Simple function definitions with and without parameters.
# Function with no parameters
def greet():
print("Hello, World!")
greet() # Call the function
# Function with parameters
def greet_person(name):
print(f"Hello, {name}!")
greet_person("Alice") # Hello, Alice!
greet_person("Bob") # Hello, Bob!Return Values
Functions that return values for use in other parts of the program.
def add(a, b):
result = a + b
return result
sum_result = add(5, 3)
print(sum_result) # 8
# Function with multiple return values
def calculate(x, y):
addition = x + y
subtraction = x - y
multiplication = x * y
return addition, subtraction, multiplication
a, s, m = calculate(10, 5)
print(f"Add: {a}, Subtract: {s}, Multiply: {m}")Default Parameters
Setting default values for parameters that can be overridden.
def create_profile(name, age=18, country="USA"):
print(f"Name: {name}")
print(f"Age: {age}")
print(f"Country: {country}")
print()
# Using all defaults
create_profile("Alice")
# Overriding some defaults
create_profile("Bob", 25)
# Overriding all
create_profile("Charlie", 30, "UK")
# Using keyword arguments
create_profile("David", country="Canada")Variable Arguments
Using *args and **kwargs to accept flexible number of arguments.
# *args - variable positional arguments
def sum_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(10, 20, 30, 40)) # 100
# **kwargs - variable keyword arguments
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="New York")
# Combining both
def display_data(title, *args, **kwargs):
print(f"=== {title} ===")
print("Positions:", args)
print("Keywords:", kwargs)
display_data("User Info", "Item1", "Item2", name="Bob", role="Admin")Docstrings and Type Hints
Documenting functions and specifying expected types.
def calculate_bmi(weight: float, height: float) -> float:
"""
Calculate Body Mass Index.
Args:
weight (float): Weight in kilograms
height (float): Height in meters
Returns:
float: BMI value rounded to 2 decimal places
"""
bmi = weight / (height ** 2)
return round(bmi, 2)
result = calculate_bmi(70, 1.75)
print(f"BMI: {result}")
# Access docstring
print(calculate_bmi.__doc__)Nested Functions
Defining functions inside other functions for encapsulation.
def outer_function(x):
print(f"Outer function received: {x}")
def inner_function(y):
return y * 2
result = inner_function(x)
print(f"Inner function returned: {result}")
return result
final = outer_function(5)
print(f"Final result: {final}")
# Practical example - validation
def process_user(name, age):
def validate_name(n):
return len(n) > 0 and n.isalpha()
def validate_age(a):
return 0 < a < 150
if not validate_name(name):
return "Invalid name"
if not validate_age(age):
return "Invalid age"
return f"User {name} ({age}) registered successfully"
print(process_user("Alice", 25))Best practices
- Use clear, descriptive function names that indicate what the function does (calculate_total, not calc)
- Keep functions focused on a single task (Single Responsibility Principle)
- Add docstrings to explain what the function does, its parameters, and return value
- Use type hints to make your function signatures clearer and enable better IDE support
- Limit function length - if it's too long, consider breaking it into smaller functions
- Use default parameter values wisely - they should represent the most common use case
At a glance
- Purpose
- Scripting and general-purpose applications
- File extension
- .py
- Runs in
- Python interpreter
- Usually used with
- Python standard library and packages
In plain English
def gives a reusable operation a name. Indentation groups the statements that belong to it.
What you’ll learn
- Define a function.
- Pass inputs.
- Return a result.
Before you start: if
Breaking down the syntax
def- Starts a function definition.
:- Begins the indented body.
return- Ends the call and supplies a value.
How it works
Define
Create the function object.
Call
Bind arguments to parameters.
Return
Send a result to the caller.
When should I use this?
Group a focused operation that needs a clear name or reuse.
Common mistakes
A common trap
The function body must be indented.
Incorrect
def double(n):
return n * 2Corrected
def double(n):
return n * 2Compare approaches
- def: Named functions with statements.
- lambda: A small function expressed by one expression.
Explore deeper
Default values are evaluated once
A mutable default such as [] is shared by calls that omit that argument. Use None as a sentinel and create a fresh list inside when each call needs its own list.
Specifications & further reading
Related Python documentation
A lambda is a small, anonymous, single-expression function, created without the def keyword or a name. Lambdas are restricted to a single expression whose result is automatically returned - they can't contain multiple statements or assignments. They're most useful as short, throwaway functions passed as arguments to other functions like sorted(), map(), and filter().return
The return statement exits a function immediately and optionally sends a value back to the caller. A function can return any type - including multiple values as a tuple - or nothing at all, in which case it implicitly returns None. Once return executes, no further code in the function runs, making it useful for early exits as well as producing a final result.*args and **kwargs
*args and **kwargs let a function accept a variable number of arguments. *args collects any extra positional arguments into a tuple, while **kwargs collects extra keyword arguments into a dictionary. The names 'args' and 'kwargs' are just convention - what matters is the * and ** prefixes. This pattern is common in wrapper functions, decorators, and APIs that need to stay flexible about their inputs.Decorators
A decorator is a function that wraps another function to extend or modify its behavior, without changing its actual source code. Decorators use the @decorator_name syntax placed directly above a function definition, which is shorthand for passing the function into the decorator and reassigning the result. They're widely used for logging, timing, access control, caching, and validation.