FULL PYTHON FIX · 6 MIN READ
Why Does My Python Function Return None After Printing?
A message on the screen is not a value returned to the caller. Trace the function's result, add an explicit return, and test how another line can use that value.
Quick fix
Replace print(number * 2) with return number * 2.
def double(number):
return number * 2
result = double(4)
print('doubled:', result)
print('plus one:', result + 1)Video guide: Why Does My Python Function Return None After Printing?
The preview is stored on this site. YouTube loads only when you press Play. Watch on YouTube
Jump to a chapter
Read the video transcript
Select a timestamp to watch that moment on YouTube.
- 00:00
This Python function seems to work. When I call double with four, the terminal shows eight. But the very next line crashes when I try to add one to the result. The last line of the traceback mentions NoneType and int. Where did None come from if we just saw eight? In this video we will separate two actions that are easy to confuse: displaying a value and returning a value. I will run the broken program before changing it so we can see both events in the same terminal. First, eight appears because the function calls print. Then Python tries to evaluate result plus one and raises TypeError. The variable result does not contain eight.
- 00:41
It contains None. We will confirm that with a diagnostic print, replace the display inside the function with a return statement, and test what a caller actually receives. This mistake often appears in homework functions that print a correct answer but fail automated tests. It also appears in larger programs when one function tries to reuse a calculation performed by another. The visible answer is not enough evidence that the function has given a usable value back to its caller. We need to inspect the returned object. Now the terminal shows eight on one line and None, NoneType on the next. The first line is a side effect of calling print inside double.
- 01:25
The second line describes the value stored in result. Python functions that reach the end without an explicit return produce None automatically. That is exactly what happened here. The call double of four executed the print, reached the end of the function, and sent None back to the assignment. The following arithmetic failed because None is not a number. There is a tempting change that would still be wrong: return print of number times two. The built-in print function itself returns None. So that version would display eight and explicitly return None. We would have changed the syntax without changing the outcome. The useful question is, what is the function's contract?
- 02:08
If its job is only to write a message to the terminal, returning None can be completely appropriate. But our caller wants to add one to the doubled number. For that contract, double must return a number. When debugging, inspect the value at the call site with repr or type instead of trusting what happened to appear on the screen. I have replaced the print inside double with return number times two. A return statement passes that integer back to the caller and ends the current function call. The assignment stores the integer eight in result. Printing result now shows eight, and adding one produces nine without an error. The placement of print matters.
- 02:49
This corrected function computes a value; the caller decides whether to display it. That makes the function useful in a script, a test, a web application, or another function. We can write print of double four when all we want is to show the answer. Or we can assign the return value and use it several times, as this example does. These are two ways to use the same calculation. Notice that we did not have to return a string such as the characters eight. The caller performs arithmetic, so an integer is the right result. The earlier TypeError was a clue about the type the caller received, and the corrected run verifies the type through successful arithmetic.
- 03:32
But successful arithmetic on one input is still only one test. Next we will check the return value directly and inspect an incomplete branch. These assertions test the object returned by double. If double still only printed eight, the first assertion would compare None with eight and fail. The test with zero checks a second input, including a value that can be mistaken for false in a condition. In real code, a function may have several branches. Imagine a describe function that returns the word positive when a number is above zero, but only prints a message for zero or a negative number. The positive path returns a string; the other path reaches the end and returns None.
- 04:17
That makes the bug intermittent. One caller may seem fine while another receives None, depending on its input. Run each meaningful branch while testing the result, not just the displayed text. A function can intentionally return None if its only job is to display information, write a file, or update an object. The problem is the mismatch between what the function supplies and what the caller expects. State the intended return type when designing the function. Then ensure every path that promises a result actually returns one. The same idea applies to functions that compute prices, parse data, or search a collection.
- 04:58
This last run makes the branch problem visible. The message not positive appears, but repr shows None as the value returned for zero. To fix describe as a calculation, replace that print with a suitable return value. On the website, your practice task is to write add_tax so it returns the price including tax. Test that a price of forty with a rate of point two returns forty-eight, and that a zero price returns zero. Print one result outside the function so you can see it, but keep the calculation separate from display. When you debug a mysterious NoneType error, trace the assignment that received None.
- 05:38
Find the function call on the right-hand side. Inspect every branch of that function for a return statement. If it prints a plausible result but never returns it, you have found the mismatch. Avoid the false fix of return print, because print returns None. Use a normal return expression and then test the value seen by the caller. The three steps are simple: identify the expected result, inspect what was actually returned, and verify with an assertion or a second calculation. You can find the full guide and interactive function lessons on PythonLessonLab through the links below this video.
Watch the function print eight and then fail
This example seems promising at first: double(4) displays 8. The next line tries to add 1 to the result and fails. The reason is that the display came from print() inside double, while the function call itself produced None. Read the final traceback line and the sequence of output carefully.
A function without a return statement returns None implicitly. The printed eight and the returned None are separate events. The caller stores the returned object in result; it does not capture whatever appeared on the screen. This distinction matters whenever a calculation is reused in another calculation, a test, or another function.
def double(number):
print(number * 2)
result = double(4)
print(result + 1)8
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'Inspect the value received by the caller
Temporarily remove the arithmetic and inspect result with repr() and type(). The function still prints 8, but the diagnostic line reports None NoneType. This is direct evidence that double did not send a usable number back. Do not assume a visible output proves that a return value exists.
The built-in print() function is for display and logging. Its own return value is None. Writing return print(number * 2) therefore does not fix this calculation: it prints the number and then returns print()'s None. Work out whether the function's job is to compute a value or only to produce a side effect. Here the caller needs a value.
def double(number):
print(number * 2)
result = double(4)
print(repr(result), type(result).__name__)8
None NoneTypeReturn the calculated number and print at the edge
Replace print(number * 2) with return number * 2. A return statement passes the value back to the caller and ends the function call. The caller can then store it, add to it, compare it, or print it. Put display code outside the calculation so the same function also works in a program without a terminal.
You can still print the result when you want a human to see it. The key is where the printing happens: print(double(4)) displays the value returned by double. In contrast, assigning result = double(4) leaves result available for later work. Both forms now use the same returned integer.
def double(number):
return number * 2
result = double(4)
print('doubled:', result)
print('plus one:', result + 1)doubled: 8
plus one: 9Test the return value, including a branch
Test the returned value directly instead of judging success only by terminal text. assert double(4) == 8 checks what the caller actually receives. A second test with zero catches a function that accidentally relies on one specific input. These checks are small, but they exercise the function's contract.
If a function has multiple branches, make sure each branch returns an appropriate value. Returning in one branch and merely printing in another can create an intermittent None bug. There are legitimate functions whose purpose is only to print or save a file; those can return None on purpose. The error occurs when the caller expects a number from such a function.
def double(number):
return number * 2
assert double(4) == 8
assert double(0) == 0
print('return values verified')return values verifieddef describe(number):
if number > 0:
return 'positive'
print('not positive')
print(repr(describe(0)))not positive
None- Printing lets a human see a value; return passes a value to the caller.
- A function that falls off the end returns None.
- Test the value returned from every branch the caller uses.
Practice the fix
Write add_tax(price, rate) so it returns the price including tax instead of printing it. Test add_tax(40, 0.2) == 48.0 and add_tax(0, 0.2) == 0.0 with assert. Then print one returned value outside the function.
Need a hint?
Inside the function use return price * (1 + rate). Put print(add_tax(40, 0.2)) after the definition, not inside it.
Python console
Ready to runEdit the code and run it in your browser. Examples above can be loaded with Try this example.
Does your code use input()? Add one value per line
Your output appears here.
Write your solution, then select Check practice.
Key takeaways
- A printed message is separate from the function's return value.
- Without an explicit return, a Python function returns None.
- Use return for a result the caller must reuse; print it outside the calculation when needed.
- Test returned values directly and check every relevant control-flow branch.