Side Effects vs. Return Values
Void functions perform actions but return None, not a usable value.
The Visible Action Trap
Many learners expect every function call to produce a value that can be stored and reused. That expectation seems reasonable when a call visibly does something. For example, print displays text on the screen. However, the action performed by a function and the value returned to its caller are separate things. A function can perform a visible action while returning no usable value.
What do you think happens?
What do you think result contains after the function call performs its printing action?
Reveal answer
Answer: None
The printing action happens on the screen, but the function does not provide a usable return value. Python represents that absence with the special value None.
Two Kinds of Function Results
A void function performs an action, often a side effect such as printing, but returns None rather than a usable value. A fruitful function computes and returns a meaningful value that the caller can store and use in later calculations.
| Function kind | What happens when it runs | What the caller receives |
|---|---|---|
| Void function | It performs an action or side effect | None |
| Fruitful function | It computes a result | A meaningful value |
The distinction is not whether the function call appears to do something. A void function may clearly change what you see on the screen or perform another action. The distinction is whether the caller receives a meaningful value for storage, calculation, or another operation.
def print_twice(text): print(text) print(text) result = print_twice('Bing') print(result)
Bing
Bing
NoneAssignment Stores None
Assignment does not capture everything a function does. It captures the value produced by the function call. In the print_twice example, the two lines of screen output are the side effect. The value assigned to result is None. The sequence is therefore: call the function, observe its action, assign its returned value, and then observe None when the variable is displayed.
Tracing a Void Function Assignment
Determine what happens when the result of an action-oriented function is assigned to a variable.
Call: The function is called and performs its action by printing the text twice.
Return: The function does not provide a usable value, so Python represents the absence of that value as None.
Assignment: The variable receives the function call's result, so the variable contains None rather than the printed text.
Later use: Displaying the variable shows None. The screen output and the returned value were separate results.
The function performs its action, but the assigned variable contains None.
What None Means
None is a special Python value with its own type, NoneType. It is not merely an empty slot, and it is not the text string 'None'. The two may look similar when displayed, but they represent different things. None signals that a function did not produce a usable value for its caller, while 'None' is text.
| Item | Meaning | Type |
|---|---|---|
| None | A special value representing no usable return value | NoneType |
| 'None' | Text containing the characters N, o, n, e | String |
Tracing an Unexpected None
A None-related bug usually begins with an incorrect expectation about the function's result. The caller expects a meaningful value, but the function is void or reaches a path that does not provide one. Trace the call from the caller into the function, identify the action it performs, and then check what value reaches the assignment. If that value is None, the function did not produce the result the caller needs.
Assuming visible output is the function's return value
Printing is an action or side effect. The function can perform that action and still return None.
Fix:
Trace the value returned by the call separately from what appears on the screen.Using a variable containing None in a calculation
None is not a usable calculation result.
Fix:
Identify whether the called function is fruitful before using its result in a calculation.Confusing None with the string 'None'
None has type NoneType, while 'None' is text.
Fix:
Keep the special value None conceptually separate from the string 'None'.
Practice the Distinction
A function call produces visible output, and its result is assigned to a variable. Explain separately what the function did as an action and what value the variable received. Then classify the function as void or fruitful and explain why.
Hints
- Do not treat screen output and a returned value as the same result.
- Ask whether the caller received a meaningful value that can be used later.
- If the function did not return a usable value, identify the special value Python uses.
You expected a variable to contain a value for a calculation, but debugging shows that it contains None. What should you inspect first: the screen output, the function's action, or the value returned to the caller? Explain your choice.
Hints
- The bug concerns the value assigned to the variable.
- A function can complete an action without returning a usable value.
- Trace the function call and identify whether it is void or fruitful.
Key Takeaways
- A void function performs an action but returns None rather than a usable value.
- A fruitful function returns a meaningful value that the caller can store and use.
- Assigning the result of a void function stores None in the variable.
- None is a real Python value of type NoneType, not the string 'None'.
- When an expected value becomes None, trace the function call and check whether the function actually returns a usable result.
Key Takeaways
- Side effects describe what a function does; return values describe what the caller receives.
- Void functions return None, even when their actions are visible.
- Fruitful functions return meaningful values that can be stored and used.
- None and the string 'None' are different, and None has type NoneType.
- An unexpected None is a debugging clue that the caller did not receive the value it expected.