Defining Functions
A function is a named, reusable block of code that performs a specific task. Instead of copying and pasting the same logic every time you need it, you wrap it in a function, give it a name, and call that name whenever you need the behavior. Functions are one of the most important tools for writing clean, maintainable Python — they let you break a large problem into small, testable pieces.
The `def` Syntax
Functions are created with the def keyword, followed by a name, a pair of parentheses (which may contain parameters), and a colon. The body of the function is indented.
def greet(name):
message = f"Hello, {name}!"
print(message)
# Calling the function
greet("Ada")
greet("Grace")Hello, Ada! Hello, Grace!
Here, greet is the function name and name is a parameter — a placeholder for a value the function expects to receive. def defines the function but does not run it; the code inside only executes when the function is called using greet(...).
Parameters vs Arguments
These two words are often used interchangeably, but they mean slightly different things:
Parameter: the name listed in the function definition (e.g.nameindef greet(name):).Argument: the actual value passed in when the function is called (e.g."Ada"ingreet("Ada")).
In practice, people say "pass an argument" and "define a parameter" — the parameter is the seat, the argument is who sits in it.
The `return` Statement
print() displays something to the console, but it does not give the value back to the rest of your program. To hand a result back to the caller, use return.
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
print(add(10, 20)) # 30, used directly8 30
As soon as Python executes a return statement, the function stops running immediately — any code after it in the same function is skipped.
def check_sign(n):
if n > 0:
return "positive"
if n < 0:
return "negative"
return "zero"
print("this line never runs") # unreachable
print(check_sign(-4))negative
Implicit `None` Return
If a function does not hit a return statement — or uses a bare return with no value — it automatically returns None. This is easy to forget and a common source of bugs.
def log_message(msg):
print(f"[LOG] {msg}")
# no return statement here
output = log_message("Server started")
print(output) # None[LOG] Server started None
Docstrings
A docstring is a string literal placed as the very first statement inside a function body. It documents what the function does and is accessible at runtime via function.__doc__ or help(function).
def area_of_circle(radius):
"""Return the area of a circle given its radius."""
pi = 3.14159
return pi * radius ** 2
print(area_of_circle(2))
print(area_of_circle.__doc__)12.56636 Return the area of a circle given its radius.
Functions Are First-Class Objects
In Python, functions are objects just like integers, strings, or lists. That means you can assign a function to a variable, store functions in a list or dictionary, and pass them as arguments to other functions.
def shout(text):
return text.upper() + "!"
# Assign the function itself (no parentheses) to a new name
yell = shout
print(yell("hello")) # HELLO!
# Store functions in a data structure
operations = {"shout": shout}
print(operations["shout"]("wow")) # WOW!HELLO! WOW!
Notice yell = shout has no parentheses — that copies a reference to the function object, not the result of calling it. This first-class nature is what makes higher-order concepts like lambdas, closures, and decorators possible in Python, which you'll meet later in this section.
Quick Reference
Concept | Example | Notes |
|---|---|---|
Definition |
| Creates the function, does not run it |
Call |
| Executes the function body |
Parameter |
| Placeholder in the definition |
Argument |
| Actual value passed at call time |
Return |
| Sends a value back, exits immediately |
No return | (nothing) or | Implicitly returns |
def average(numbers):
"""Return the average of a list of numbers, or None if empty."""
if not numbers:
return None
return sum(numbers) / len(numbers)
print(average([4, 8, 15, 16, 23, 42]))
print(average([]))18.0 None