Functions let you package a block of code under a name and reuse it whenever you need it, instead of retyping the same logic over and over. This guide covers how to define, call, and return values from Python functions, step by step.
If you’ve followed our guides on if statements and for loops, you’re ready for one of the most important building blocks in Python: the function. Nearly everything you write from here on out — from small scripts to full applications — will be organized around functions calling other functions.
This guide covers what a function actually is, how to define and call one, how parameters and return values work, and default arguments, which make functions genuinely flexible.
What a Function Actually Is
A function is a named, reusable block of code that performs a specific task. According to Python’s official tutorial, the keyword def introduces a function definition, and it must be followed by the function’s name and a parenthesized list of parameters.
def greet():
print("Hello!")
greet() # calls the function, printing "Hello!"Defining a function — the first block above — doesn’t run its code immediately; it just stores the instructions under the name greet. The code only actually runs when you call the function using its name followed by parentheses.
Parameters and Arguments
Most useful functions accept input, so they can behave differently depending on what’s passed to them. According to freeCodeCamp’s guide to defining and calling functions, you specify parameters inside the parentheses of the function definition, and supply the actual values (called arguments) when you call the function.
def greet(name):
print(f"Hello, {name}!")
greet("Alex") # Hello, Alex!
greet("Sam") # Hello, Sam!Here, name is the parameter — a placeholder that stands in for whatever value gets passed in. "Alex" and "Sam" are the arguments — the actual values supplied each time the function is called. This distinction trips up a lot of beginners at first, but it’s simply describing the same value from two different perspectives: the placeholder versus the real thing passed in.
Returning a Value
So far, the example functions have only printed something. Often you want a function to calculate a value and hand it back to whatever called it, rather than just printing it. That’s what the return keyword does:
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 8According to W3Schools’ introduction to Python functions, a function can return data as a result using the return statement — without it, calling a function that only prints something and trying to store its result in a variable will simply give you None, Python’s way of representing “nothing was returned.”
Once a return statement runs, the function stops immediately — any code written after it inside the same function never executes. This is a useful detail to remember once your functions get slightly more complex.
Default Parameter Values
Sometimes you want a parameter to have a sensible fallback value if the function is called without providing one. Python lets you define this directly in the function’s parameter list:
def greet(name="friend"):
print(f"Hello, {name}!")
greet("Alex") # Hello, Alex!
greet() # Hello, friend!Without a default value, calling greet() with no argument would raise an error, since Python requires a value for every parameter that doesn’t have a default. Default parameters are a small, clean way to make a function more forgiving without adding extra conditional checks inside its body.
Positional vs. Keyword Arguments
By default, Python matches arguments to parameters based on their order — this is called a positional argument. You can also pass arguments by explicitly naming the parameter, called a keyword argument, which lets you supply them in any order and makes the call more readable:
def describe_pet(name, animal_type):
print(f"{name} is a {animal_type}.")
describe_pet("Rex", "dog") # positional
describe_pet(animal_type="dog", name="Rex") # keyword, same resultKeyword arguments are especially useful once a function has several parameters, since they make it immediately clear at the call site which value maps to which parameter, without needing to memorize the exact order they were defined in.
Function Scope: What a Function Can and Can’t See
Variables created inside a function only exist inside that function — this is called scope. Once the function finishes running, those variables disappear, and code outside the function has no way to access them:
def calculate_total():
tax = 0.08
return 100 * (1 + tax)
print(tax) # NameError: name 'tax' is not definedThis isn’t a limitation to work around — it’s a genuinely useful feature. Keeping a function’s internal variables contained means you don’t have to worry about accidentally overwriting a variable somewhere else in a large program just because you happened to reuse a common name like total or count inside a function.
A Practical Example
Here’s a slightly larger example that ties functions together with the loops and conditions covered earlier in this series:
def is_even(number):
return number % 2 == 0
numbers = [1, 2, 3, 4, 5, 6]
for num in numbers:
if is_even(num):
print(f"{num} is even")
else:
print(f"{num} is odd")This defines a small, reusable function that checks whether a number is even, then calls it once for each item in a list — a genuinely common pattern once you start combining functions with loops and conditions together.
Accepting a Variable Number of Arguments
Sometimes you don’t know in advance how many arguments a function will need to accept. Python handles this with *args, which collects any number of extra positional arguments into a tuple:
def add_all(*numbers):
total = 0
for num in numbers:
total += num
return total
print(add_all(1, 2, 3)) # 6
print(add_all(1, 2, 3, 4, 5)) # 15This same function works whether you pass it two numbers or ten, without needing to define a fixed number of parameters ahead of time. A related tool, **kwargs, does the equivalent for keyword arguments, collecting them into a dictionary — genuinely useful once you’re writing functions meant to be flexible about exactly what gets passed in.
Documenting a Function With a Docstring
Right after a function’s definition line, you can include a short string describing what it does — called a docstring. This isn’t required, but it’s a widely used, genuinely helpful habit:
def calculate_area(length, width):
"""Return the area of a rectangle given its length and width."""
return length * widthDocstrings show up automatically when someone uses Python’s built-in help() function on your code, and many code editors display them as a tooltip the moment you start typing a function call — meaning a good docstring pays for itself the very next time you (or anyone else) uses that function, without needing to open and re-read its actual implementation.
Functions Calling Other Functions
Real programs are rarely built from a single, standalone function — instead, small functions call other small functions, each handling one clear piece of a larger task:
def square(n):
return n * n
def sum_of_squares(numbers):
total = 0
for num in numbers:
total += square(num)
return total
print(sum_of_squares([1, 2, 3])) # 14Here, sum_of_squares relies on square to do part of its work, rather than repeating the squaring logic inline. Breaking a task into small, named, single-purpose functions like this — sometimes called decomposition — is one of the most transferable skills in programming, and it applies just as directly to JavaScript, or any other language you eventually learn.
Common Questions Beginners Ask About Functions
Do all functions need to return a value? No. A function that doesn’t include a return statement simply returns None by default, which is perfectly fine for functions whose whole purpose is an action, like printing something, rather than producing a value to use elsewhere.
What if I call a function with the wrong number of arguments? Python raises a TypeError immediately, telling you exactly how many arguments were expected versus how many were given — a genuinely helpful, specific error message compared to some other languages that fail more silently.
Can a function call itself? Yes — this is called recursion, and it’s a genuinely powerful technique for certain kinds of problems, though it’s worth treating as an advanced topic to revisit once basic functions feel completely comfortable. Most everyday tasks don’t require it.
Quick-Reference Python Functions Guide
- def function_name(): — defines a function; the code doesn’t run until called.
- Parameters — placeholders defined with the function.
- Arguments — actual values passed in when calling the function.
- return — sends a value back and immediately stops the function.
- Default parameters — provide a fallback value if none is supplied.
- Keyword arguments — let you pass values by name, in any order.
Conclusion
Functions are the tool that turns repetitive code into something reusable, and understanding parameters, arguments, and return values covers the overwhelming majority of what you’ll need for a long time. Once this pattern clicks, you’ll find yourself naturally reaching for a function anytime you notice yourself writing similar code more than once.
The best way to build real comfort here is writing a handful of small functions yourself — something that adds two numbers, something that greets a name, something that checks a condition — rather than only reading through the examples above.
In the next guide in this series, we’ll cover Python lists and tuples — how they differ, and when to reach for each one.
Explore More Python for Beginners Guides →

When not writing, Alex is probably debugging someone else’s code.