A Python function is a named block of code that performs specific tasks and can be reused in other parts of your code. Python has several built-in functions that are always available, and you can also create your own. These are known as user-defined functions.
To define a function in Python, you use the def keyword, followed by the function name and an optional list of parameters enclosed in a required pair of parentheses. You can call and reuse a function by using its name, a pair of parentheses, and the necessary arguments.
Learning to define and call functions is a fundamental skill for any Python developer. Functions help organize your code and make it more modular, reusable, and easier to maintain.
By the end of this tutorial, you’ll understand that:
- A Python function is a self-contained block of code designed to perform a specific task, which you can call and reuse in different parts of your code.
- You can define a Python function with the
defkeyword, followed by the function name, parentheses with optional parameters, a colon, and then an indented code block. - You call a Python function by writing its name followed by parentheses, enclosing any necessary arguments, to execute its code block.
Understanding functions is key to writing organized and efficient Python code. By learning to define and use your own functions, you’ll be able to manage complexity and make your code easier to read.
Get Your Code: Click here to download the free Python code that shows you how to define your own function in Python.
Take the Quiz: Test your knowledge with our interactive “Defining Your Own Python Function” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Defining Your Own Python FunctionIn this quiz, you'll test your understanding of defining and calling Python functions. You'll revisit the def keyword, parameters, arguments, and more.
Python for Beginners Live Course: Want to practice writing your own functions with an instructor? In Real Python’s Python for Beginners live course, you go from variables and control flow to functions and projects of your own, with live help in a small group. Join the waitlist to hear about the next dates.
Getting to Know Functions in Python
In mathematics, a function is a relationship or mapping between one or more inputs and a set of outputs. This concept is typically represented by the following equation:

Here, f() is a function that operates on the variables x and y, and it generates a result that’s assigned to z. You can read this formula as z is a function of x and y. But how does this work in practice? As an example, say that you have a concrete function that looks something like the following:

Now, say that x is equal to 4 and y is 2. You can find the value of z by evaluating the function. In other words, you add 4 + 2 to get 6 as a result. That’s it!
Functions are also used in programming. In fact, functions are so fundamental to software development that virtually all modern, mainstream programming languages support them. In programming, a function is a self-contained block of code that encapsulates a specific task under a descriptive name that you can reuse in different places of your code.
Many programming languages have built-in functions, and Python is no exception. For example, Python’s built-in id() function takes an object as an argument and returns its unique identifier:
>>> language = "Python"
>>> id(language)
4390667816
The integer number in this output uniquely identifies the string object you’ve used as an argument. In CPython, this number represents the memory address where the object is stored.
Note how similar this notation is to what you find in mathematics. In this example, language is equivalent to x or y, and the pair of parentheses calls the function to run its code, comparable to evaluating a math function. You’ll learn more about calling Python functions in a moment.
Note: To learn more about built-in functions, check out Python’s Built-in Functions: A Complete Exploration.
Similarly, the built-in len() function takes a data collection as an argument and returns its length:
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> items = len(numbers)
>>> items
10
In this example, the list of numbers has ten values, so len() returns 10. You assign this value to the items variable, which is equivalent to z in the mathematical equation you saw before.
Most programming languages—including Python—allow you to define your own functions. When you define a Python function, you decide whether it takes arguments. You’re also responsible for how the function internally computes its result.
Once you’ve defined a function, you can call it from different parts of your code to execute its specific computation or action. When the function finishes running, it returns to the location where you called it.
With this quick introduction to Python functions, you’re ready to dive deeper into creating and using functions in your code. First, you’ll examine some of the main benefits of using functions.
Exploring Some Benefits of Functions
So, why should you bother defining and using functions in Python? What are their benefits? There are several good reasons to define and use functions in your code. In the following sections, you’ll explore some of these benefits.
Abstraction
Abstraction is about managing complexity by exposing a simplified interface to the user or programmer, while keeping the internal workings of a piece of code private or irrelevant to the context of use. You can do this by hiding a given functionality inside a function and exposing only the function’s interface, consisting of its name and expected arguments, to the rest of the program.
For example, in previous sections, you used some Python built-in functions even though you don’t know how they’re implemented internally. You only knew the function’s name and its arguments. So, built-in functions abstract the implementation details and only show you a user-friendly interface.
Defining custom functions enriches your vocabulary by introducing new black boxes that the language didn’t originally have. This increases your code’s readability by using descriptive function names that unambiguously identify specific tasks, rather than using long sequences of statements without an obvious, visible goal.
Encapsulation
Encapsulation refers to bundling data and behaviors into a single unit and restricting direct access to some of these components.
When you call a function, Python creates a dedicated namespace for that function call. This namespace will hold the names you define inside the function. It’s a namespace distinct from all other existing ones, such as the global and built-in namespaces.
The practical upshot of this behavior is that the variables defined within a function are only accessible from within the function itself, which allows for data encapsulation.
Even when function’s local variables have the same names as outer variables, there will be no confusion or interference because they’re in separate namespaces. So, you can’t modify the function’s behavior by altering the value of a given local variable from the outside, whether by accident or on purpose.
Modularity
Modularity is a design principle that divides a program into separate, independent, and interchangeable components. Each component is a self-contained unit that encapsulates a specific part of the program’s functionality.
Functions allow you to divide a large program into smaller chunks that perform a specific task, making your code modular.
Imagine, for example, that you have a program that reads in a file, transforms its contents, and writes the result to a different file. You could handle these operations as a plain sequence of statements:
# Main program
# Read the file
<statement_0>
<statement_1>
...
<statement_n>
# Process the file
<statement_0>
<statement_1>
...
<statement_n>
# Write the result to another file
<statement_0>
<statement_1>
...
<statement_n>
In this example, your program is a bunch of sequential statements, with whitespace and comments to help organize it. However, if the code were to get much longer and more complex, then you’d have an increasingly difficult time wrapping your head around it.
Alternatively, you could structure the code as shown below:
def read_file():
<statement_0>
<statement_1>
...
<statement_n>
def process_file():
<statement_0>
<statement_1>
...
<statement_n>
def write_file():
<statement_0>
<statement_1>
...
<statement_n>
# Main program
read_file()
process_file()
write_file()
In this example, you modularize the code. Instead of all the code being strung together, it’s broken into separate functions, each focusing on a specific task. Those tasks are read, process, and write. The main program now calls each of these functions in turn.
Note: The def keyword lets you define a new function in Python. You’ll learn all about this keyword in the section on function definition.
As programs become more complicated, modularizing them with functions becomes increasingly beneficial. Breaking a task into smaller subtasks helps you manage complex programming problems. It also facilitates debugging because you can focus on simpler tasks that are often easier to debug than complex and overly long tasks.
Reusability
Reusability is the ability to use existing code in new contexts without repeating the code itself. It implies writing code in a way that allows you to use it multiple times across different parts of a program, or even across multiple projects, with little or no modification.
Suppose you’ve written some code that does something useful. As you continue development, you find that the code performs a task you often need in many different locations within your program. What should you do?
Say that you decide to replicate the code over and over again, using your editor’s copy-and-paste capability. What would happen if you later realize that the piece of code in question must be modified or updated? If copies of the code are scattered all over your program, then you’ll need to make the necessary changes in every location.
Code duplication can lead to another issue. If a developer updates most but not all instances of the repeated code, this can result in inconsistencies in data or behavior across the program.
A better solution is to define a Python function that performs the task. Then, you can call the function from any part of your program that you need to accomplish the task. Down the line, if you decide to change how the code works, then you only need to change the code in one location: the function’s definition. The changes will automatically be picked up anywhere you call the function.
Note: Functions aren’t a one-size-fits-all solution. Sometimes, repeating a chunk of code in multiple places would be the best approach, especially if you’re working with code where the execution speed is critical. In this scenario, repeating the code might be faster than calling the function multiple times, because function calls might add significant speed overhead to the code.
The don’t repeat yourself (DRY) principle of software development is a strong motivation for using functions. Functions help eliminate repetitive code. They also allow you to align with other core software engineering principles, such as the single-responsibility principle (SRP).
Maintainability
In programming, maintainable code refers to code that you can quickly and easily understand, correct, enhance, or adapt over time. A maintainable codebase is clear, well-structured, and modular, allowing developers to make changes with minimal risk of introducing bugs.
Functions help with code maintainability because they allow you to do the following:
- Break down code into logical parts
- Encourage reuse and consistency
- Reduce duplication and errors
- Facilitate testing and debugging
- Encourage clear documentation
In short, functions are a great tool for writing maintainable code. This type of code is easier to improve and scale with new features, which is often a common need.
Testability
Testability refers to how easy it is to effectively test a piece of code to ensure it behaves as expected. You have a piece of testable code if it’s straightforward to write automated tests that verify its correctness.
Writing functions with clear arguments and explicit return values makes your code easier to test and predict. When you avoid side effects in your functions and follow the single responsibility principle, they become easier to reason about. Additionally, keeping your functions small and readable further enhances their quality. Together, these practices greatly improve the testability of your code.
Defining Functions in Python
Now it’s time to start defining your own functions in Python. The general syntax for defining a function is shown below:
def function_name([parameters]):
<block>
Below, you have a breakdown of this syntax’s components:
| Component | Description |
|---|---|
def |
The keyword that begins the function definition |
function_name |
A valid Python identifier that names the function |
[parameters] |
An optional, comma-separated list of formal parameters for the function |
: |
The punctuation that denotes the end of the function header |
<block> |
The function’s code block |
The final item, <block>, is usually called the function’s body. The body is a series of statements that will run when you call the function. The body is defined by indentation. This is the same as code blocks associated with a control structure, like an if or while statement.
Note: Python has what are known as lambda functions. These allow you to create custom anonymous functions whose bodies consist of a single expression. This tutorial doesn’t cover this type of function. To learn more about them, check out How to Use Python Lambda Functions.
Here’s your first Python function:
>>> def greet(name):
... print(f"Hello, {name}!")
...