def, return, None, and Call Flow

Key Takeaways

  • A def statement creates a function object at definition time; the indented body does not run until the function is actually called.
  • A function that reaches the end of its body without executing a return statement returns None implicitly.
  • print() displays text on standard output and itself evaluates to None, while return sends a value back to the caller.
  • Once a return statement executes, the current function call ends and any later statements on that path are skipped.
  • Nested function calls are resolved innermost-first; the inner return value becomes the outer call's argument.
Last updated: June 2026

Why call flow matters on PCEP

The PCEP-30-02 exam asks 30 questions in 40 minutes (about 80 seconds each, 70% to pass). Functions-and-exceptions items rarely ask you to write code; they show a short snippet and ask what it prints, returns, or raises. To answer fast and correctly, separate three distinct moments: Python reads the def statement, the program calls the function, and the caller uses whatever value comes back.

A def statement binds a name to a function object. The indented body is compiled and stored, not executed. The body runs only when the name is followed by parentheses with the required arguments.

def double(n):
    print('inside')
    return n * 2

print('before')
value = double(4)
print(value)

The output is before, then inside, then 8. Defining double printed nothing. The assignment value = double(4) receives the return value 8; it does not receive the word printed inside the body.

return versus print: the most-tested distinction

Featureprint()return
Main jobWrites text to standard outputSends a value back to the caller
Value of the expressionAlways NoneThe returned object
Can be stored/combinedNo (you store None)Yes
Ends the function callNoYes, immediately
Common PCEP trapAssuming printed text is "the result"Code after return is silently skipped

A function may both print and return in one call, but the actions are unrelated. If a question asks for output, count only printed text. If it asks for the value assigned to a variable, follow the return value.

def label(x):
    print('item', x)

result = label(3)
print(result)

This prints item 3 and then None. label has no return statement, so when the body ends Python supplies None automatically, and that None is what result stores.

Three ways a function returns None

There are exactly three common paths to an implicit or explicit None:

  • The function has no return statement at all.
  • The function executes a bare return with no expression after it.
  • Execution falls through a branch where no return is reached.
def sign(n):
    if n > 0:
        return 'positive'
    if n == 0:
        return

print(sign(5))
print(sign(0))
print(sign(-2))

The three calls print positive, None, and None. The zero call hits a bare return; the negative call runs off the end of the body. Both yield None by different routes, and PCEP loves to mix the two in one snippet.

Reading nested calls

When calls are nested, resolve the innermost call first, then pass its return value outward.

def add_one(n):
    return n + 1

def show(n):
    print(n)
    return n * 10

answer = show(add_one(2))

First add_one(2) returns 3. Then show(3) prints 3 and returns 30. Finally answer becomes 30. Note a name without parentheses is just a reference: tool = show runs no body, while tool(3) does.

A repeatable exam tracing routine

Use this checklist on every function snippet so you never confuse output, function objects, and return values:

  1. Mark every def as a definition only; do not execute its body yet.
  2. Find the first actual call at the top level.
  3. Bind arguments to parameters for that call.
  4. Trace the body until a return, an exception, or the natural end.
  5. Replace the entire call expression with the value it returned.
  6. Continue at the line after the call.

Worked trap. Consider x = print('hi'). Many candidates pick 'hi' as the value of x. Wrong: print displays hi but evaluates to None, so x is None. Then print(x + 1) would raise TypeError because None + 1 is invalid. Recognizing that print returns None is worth several marks across the exam.

The routine is slower than guessing but far faster than rereading a snippet three times. On PCEP, the difference between definition and call, and between print and return, is frequently the entire question.

More patterns the exam reuses

A few additional behaviors of call flow show up repeatedly and are worth drilling until automatic.

A function object is a first-class value. You can store it, pass it, and call it later. The presence or absence of parentheses is the whole difference between referencing and calling. In funcs = [double], no body runs; funcs[0](5) is what finally calls it. PCEP often plants a bare function name in a list or assignment to see whether you mistake the reference for a call result.

Multiple return values are really one tuple. Writing return a, b returns a single tuple (a, b). The caller can unpack it with x, y = f(). If a snippet stores the result in one variable, that variable holds the whole tuple, not just the first item.

A return inside a loop exits the entire function, not just the loop. Compare with break, which only leaves the loop and lets later statements run:

def first_even(nums):
    for n in nums:
        if n % 2 == 0:
            return n
    return None

print(first_even([1, 3, 4, 7]))

This returns 4 the instant the loop finds an even number; the loop and the function both end, and the trailing return None never runs. Whenever you see a return inside a loop, stop tracing the loop the moment it fires.

Quick contrast table:

StatementLeaves loop?Leaves function?
breakYesNo
continueNo (skips to next iteration)No
returnYesYes

Keeping these three apart prevents the classic mistake of thinking code after a return-in-a-loop still executes.

Test Your Knowledge

A Python function finishes executing its body without ever reaching a return statement. What value does the call evaluate to?

A
B
C
D
Test Your Knowledge

Why does print() behave differently from return in a PCEP output question?

A
B
C
D
Test Your Knowledge

Given the body return 2 followed by print(3) on the next line, what happens to print(3) when the function is called?

A
B
C
D