Define and Call Python Functions

Learn the exact syntax for defining and calling Python functions with the def keyword, including naming rules, the function body, and how the call stack works.

7 min read

Now that you understand what functions are and why they matter for organizing Python code, you need the concrete syntax: the exact characters you type to create a function and the exact characters you type to make it run. The mechanics are simple, a single keyword and a few punctuation marks, but understanding the details of definition, calling, and the call stack will prevent a large number of confusing errors later.

Every function you will ever write in Python starts with the def keyword. This is a reserved word that signals "I am about to define a function." After def comes the function name, then a pair of parentheses, then a colon. The indented lines that follow are the function body, the code that actually executes when the function is called. This structure is not arbitrary; it is the same pattern that governs if statements and while loops, where a keyword introduces a block, a colon marks the start of the block, and indentation defines its boundaries. If you have worked through the earlier sections on Python control flow, this pattern will already feel familiar.

Before writing your own functions, you were already calling functions by writing their names followed by parentheses. The print call that has appeared in nearly every example in this learning path is a function call. The len call that measures the size of a collection is a function call. The parentheses are the signal that tells Python to execute the function rather than just refer to it. A function name without parentheses is a reference to the function object itself, a useful concept for later topics like higher-order functions, but almost certainly a bug if you intended to run the function.

The anatomy of a function definition

The simplest function takes no parameters, performs some action, and returns nothing explicitly. It looks like this:

pythonpython
def greet():
    print("Hello from the function!")

The def keyword opens the definition. The name greet is what you will use to call this function later. The empty parentheses mean the function accepts no parameters, it does not need any input to do its job. The colon tells Python that an indented block follows. The single indented line is the body, and because it is indented under the def line, Python knows it belongs to the greet function and not to the surrounding code.

This function does nothing when Python first reads the file and encounters the def line. The definition is a promise, not an action. Python remembers the function's name, its parameter list, and the location of its body in memory, but it does not execute the body until the function is called. This is the same distinction that applies to variables: assigning a value to a variable does not print it, and defining a function does not run it. To execute the function, you call it by writing its name followed by parentheses:

pythonpython
greet()

This line triggers Python to jump into the function body, run the print statement, and then return to the line after the call. If you put three greet calls in a row, the greeting prints three times. The function body runs once per call, every call is independent, and no call remembers anything from the previous call unless you explicitly store state somewhere outside the function.

Naming functions in Python

Function names follow the same rules as variable names: they must start with a letter or underscore, they can contain letters, digits, and underscores, and they are case-sensitive. Beyond those technical rules, Python has strong conventions about how functions should be named. Use snake_case: lowercase words separated by underscores. Choose verb phrases that describe what the function does. A function called process is vague; a function called normalize_phone_number tells you exactly what to expect. Good examples from real Python codebases include calculate_discount, validate_email_address, fetch_weather_data, and build_error_response.

Avoid single-letter function names. While a function named f is valid Python, it communicates nothing to a reader and forces them to read the function body. Reserve single-letter names for local variables inside very short loops. Also avoid using the names of Python built-in functions as your own function names. Defining a function called len or print shadows the built-in and makes it unavailable inside the scope where your definition lives, which leads to confusing bugs that are hard to trace.

How Python executes a function call

When Python encounters a function call like greet(), it follows a precise sequence of steps that explains behavior that otherwise seems mysterious. Python first evaluates any arguments inside the parentheses. It then looks up the name greet to find the function object. If the name does not exist in the current scope, Python checks the enclosing scopes, the global scope, and finally the built-in namespace, raising a NameError if the name is not found anywhere.

If the lookup succeeds, Python pushes a new frame onto the call stack. A frame is a data structure that holds the function's local variables, the current line number being executed, and a reference back to the calling code so Python knows where to return. Python then jumps to the first line of the function body and begins executing. When execution reaches the end of the function body or hits a return statement, Python pops the frame off the stack and resumes execution at the point right after the function call.

The call stack is what makes nested function calls possible. If greet called another function inside its body, Python would push a second frame onto the stack, run that function to completion, pop its frame, and then continue inside greet where it left off. You can see the call stack in action whenever you read a Python error message that contains a traceback: each line in the traceback corresponds to one frame on the call stack at the moment the error occurred. This is the same mechanism explained in the article on reading Python error messages.

Functions that accept input

Most useful functions take input, and you specify what input they expect by listing parameter names inside the parentheses. The parameter is a local variable that exists only inside the function body. When you call the function with an argument, Python assigns that argument to the parameter and then runs the body:

pythonpython
def greet_person(name):
    print(f"Hello, {name}!")
 
greet_person("Ada")

The parameter name acts as a placeholder that receives the concrete value, called an argument, that the caller supplies. You can call the function with different arguments, and each call binds the parameter to a different value. A function can accept multiple parameters by separating them with commas. The order of the arguments in the call must match the order of the parameters in the definition, at least for the basic positional calling style covered here. The full story of parameters includes default values, keyword arguments, and the special args and kwargs patterns, and those topics get dedicated articles later in this section starting with Python function parameters and arguments.

Defining functions before calling them

Python reads and executes your file from top to bottom, and a function must exist before any code that tries to call it. This is a common beginner mistake: writing a call to a function at the top of a script and defining that function at the bottom. Python reaches the call first, looks up the name, finds nothing, and raises a NameError. The conventional solution is to put all function definitions near the top of your file, after the imports and any module-level constants, and before the main program logic. Some developers prefer to define the main logic in a function called main and then call it at the very bottom of the file. Both patterns keep the definitions ahead of the calls and avoid the NameError.

Writing functions that do one thing

The best functions are short, focused, and self-contained. A function called process_order should process an order, not process the order, send a confirmation email, update the inventory, and log analytics. When a function does too many things, it becomes hard to name because no short name captures all its responsibilities, hard to test because you have to set up conditions for every responsibility, and hard to reuse because you rarely need all of its behaviors at once.

When you notice a function growing long or handling multiple concerns, extract the subtasks into their own functions. The original function becomes a coordinator that calls smaller, well-named functions in sequence. Each function does exactly one thing, and the coordinator function describes the overall workflow without getting tangled in the details of payment processing or email formatting. This style of programming, composing small functions into larger ones, is the foundation of maintainable Python code.

Rune AI

Rune AI

Key Insights

  • Define a function with the def keyword followed by the function name, parentheses, a colon, and an indented body.
  • Call a function by writing its name followed by parentheses; if the function accepts parameters, pass arguments inside the parentheses.
  • A function must be defined before it is called; Python reads code from top to bottom.
  • Use clear verb-based names in snake_case such as calculate_total, print_report, and validate_input.
  • The call stack tracks which function called which, and Python unwinds it automatically when each function returns.
RunePowered by Rune AI

Frequently Asked Questions

What does the def keyword do in Python?

The def keyword tells Python that you are starting a function definition. It must be followed by the function name, a pair of parentheses that may contain parameter names, and a colon. The indented block that follows is the body of the function, the code that runs when the function is called.

Can I call a Python function before I define it?

No. Python reads and executes code from top to bottom. A function must be defined before any line that calls it. If you try to call a function that appears later in the file, Python raises a NameError because the function name does not exist yet at the point of the call.

What naming conventions should I follow for Python functions?

Use lowercase letters and separate words with underscores. Function names should be verbs or verb phrases that describe what the function does: calculate_total, validate_email, fetch_user_data. Avoid single-letter names except in very short examples. The Python style guide, PEP 8, recommends snake_case for function names.

Conclusion

Defining and calling functions is the core mechanical skill that everything else in this section builds on. The def keyword starts a definition, the indented body holds the logic, and parentheses after the function name trigger execution. Write short functions with clear verb names, call them after they are defined, and let the call stack handle the flow of execution for you.