Python Programming · Foundations

Functions

Want it in plain words first? Jump to Eli explains — the same idea, no jargon.
On this page 9 sections
  1. In 30 seconds
  2. Why this matters
  3. The college version
  4. Eli explains
  5. Worked example
  6. Key takeaway
  7. Quick check
  8. Study tools
  9. Sources & references

In 30 seconds

A Python gives a name to a small, reusable piece of behavior. Write a definition with def, an indented body, and a meaningful name; the body is saved, not run immediately. Write the name followed by parentheses to call it later. This separation lets a program ask for the same job in several places without copying the job's steps each time.

Why this matters

Functions are a practical way to keep programs understandable as they grow. A well-named function turns several implementation steps into one readable action, so a reader can first follow what the program is doing and inspect details only when needed. Reuse also gives maintenance a single home: when a repeated behavior changes, its definition can change once. Small functions are easier to run, inspect, and test than one long script.

The college version

A definition records behavior; a call requests it

A function is a named unit of behavior. In Python, def begins a definition. It is followed by a name, parentheses, a colon, and an indented suite of statements. When the interpreter reaches this definition, it creates a function object and associates the chosen name with it. The body does not run merely because the definition appears in the file. That fact is useful: a program can establish many available actions before choosing which ones to perform.

A call is the later act of requesting one of those actions. In the simplest form, a call is the name followed by parentheses, as in show_banner(). Each call starts the body again from its first statement. A definition is therefore like putting a labeled tool on a workbench; a call is picking up that tool to do its job. Do not confuse a name such as show_banner with the call show_banner(): the parentheses are what make this example invoke the function. This lesson deliberately leaves the values inside those parentheses to Function Parameters and leaves results passed back to Return Values.

Readable boundaries and small responsibilities

A function creates a boundary in a program. Code outside the definition can use the function's name without needing to read every statement inside it at that moment. This is : a useful name communicates the job while hiding routine detail temporarily. display_welcome_message() says more about a program's intent than three copied print statements scattered through a file. The detail is still available in the definition when it needs inspection.

That boundary works best when the name names one coherent responsibility. A function named print_divider should print a divider, not also read a file, change a menu, and save a report. Small responsibilities make calls predictable and definitions easier to revise. They also support : instead of trying to write an entire program in one uninterrupted block, identify the smaller actions it needs and give each action a name. Decomposition is not a demand to make every line its own function; it is a way to choose useful boundaries around behavior that would otherwise be repeated, obscure, or difficult to check.

Reuse, documentation, and checking behavior

Copying a block of code may appear quick, but copied blocks can drift apart. If a greeting must change in four copied locations, one location may be missed. A shared function gives the behavior one definition and many calls. That makes a change more local and lets the name act as a compact explanation wherever it is called. Reuse is not limited to exact repetition: it also lets one part of a program call a behavior that another part has already defined.

Python permits a documentation string, or , as the first statement of a . A docstring is a concise explanation intended for people and tools; it does not replace a clear name or correct behavior. A short function can also be checked directly: call it, observe its intended visible effect, and compare that observation with the expected result. Larger testing techniques belong to Basic Testing, but the design benefit begins here. When a function's responsibility is narrow, a check can focus on that responsibility instead of untangling an entire program.

Consider a program that needs the same divider before several sections. Defining print_divider once makes the sequence of actions readable: call the name whenever the divider is wanted. The body is indented, so Python knows which statements belong to the function. Calls can occur later in the file and can occur more than once. This is not magic or a shortcut around understanding: the program still performs every statement in the body on each call. The gain is that the statements have one trustworthy home and a name that states their purpose.

Eli, the EliExplains learning guide

Eli explains

The same idea, in plain words

Explain it like I’m 10

A function is a labeled instruction card. Writing the card does not make anything happen; it only puts the instructions where the program can find them. Calling the function is like saying, ‘Use the card now.’ The program follows the steps on the card each time it hears that call. Because the card has a name, you do not need to rewrite the same steps in every place that needs them. A helpful label also lets another reader understand the job before studying the instructions themselves.

Picture it like this

Think of a function as a button labeled ‘ring bell.’ Installing the button is the definition. Pressing it is the call. Many people can press the same button, and the bell action stays in one place.

Where the picture stops working

A software function can run many kinds of statements and may have no physical effect at all. The button image only explains the separation between setting up a named action and requesting it.

Worked example

This program defines one behavior, then calls it twice. Run it with Python 3:

def print_divider():
    """Display a simple section divider."""
    print("-" * 12)

print("Morning")
print_divider()
print("Afternoon")
print_divider()

Output:

Morning
------------
Afternoon
------------

The def block establishes print_divider; it produces no divider at definition time. Each later print_divider() call runs the two statements in its body. The repeated output comes from two calls to one definition, not from two copied definitions. The docstring is the first body statement and describes the function for readers and documentation tools.

Key takeaway

Define a function once with def and an indented body, then call its name with parentheses whenever that focused behavior is needed. A good name and small responsibility make the program easier to read, reuse, and check.

Quick check

3 questions here, of 5 in this lesson’s practice set. Answers stay hidden until you check.

Question 1 of 3foundational

What does a Python def statement do in this lesson's basic model?

Choose an answer, then check it.
Question 2 of 3foundational

Which expression calls a previously defined function named print_divider?

Choose an answer, then check it.
Question 3 of 3intermediate

A script prints the same section divider in five places. Which change best uses a function?

Choose an answer, then check it.
Practice all 5

Keep learning

Ready to build on this? Continue to the next lesson.

Practice this lesson
Study tools & related lessonsYou’ll learn to · Common mistakes · Easily confused · Key vocabulary · Related

You’ll learn to

  • Define a Python function and distinguish its definition from its call.
  • Identify the role of def, parentheses, the colon, and indentation in a basic definition.
  • Explain how a function name supports reuse and abstraction.
  • Apply a function call to execute a previously defined behavior.
  • Evaluate whether a repeated task should become a small named function.

Common mistakes

  • Expecting a function body to run as soon as def is encountered.

    A definition creates the named function; add a call with parentheses where execution is wanted.

  • Writing a call name without parentheses when the behavior should run.

    Use print_divider() to call the function, not just print_divider.

  • Forgetting to indent the statements that belong to a function.

    Indent the body consistently after the definition line so Python forms the intended suite.

  • Putting unrelated jobs into one vaguely named function.

    Choose a focused responsibility and a name that tells callers what that responsibility is.

Easily confused

function definition vs. function call

A definition creates a named behavior for later use; a call requests that behavior's execution now.

reused function vs. copied code

A reused function keeps one definition with multiple calls; copied code creates multiple places that can diverge.

Key vocabulary

function
A named, callable unit of code that groups statements for a particular behavior.
function definition
The def statement and indented body that create a named function for later use.
function call
An expression that uses a function name with parentheses to request that function's execution.
function body
The indented suite of statements that a function executes when it is called.
abstraction
Using a meaningful interface or name for a behavior while temporarily setting aside its implementation details.
decomposition
Breaking a larger task into smaller, understandable responsibilities.
docstring
A string literal placed first in a function body to document that function for people and tools.

Sources & references

  1. The Python Tutorial — 4. More Control Flow Tools (if Statements) — Python Software Foundation
  2. Think Python, 2e — Chapter 3: Functions — Allen B. Downey / Green Tea Press

EliExplains lessons are original prose written from the open, credible references above. See Copyright & Licensing.

Researched 2026-08-19

Educational content only. It is not medical, legal or professional advice. Found an error? Tell us.