Ever written a Python function that seems to do nothing? It’s a classic beginner bug, and it usually boils down to one subtle mistake: confusing print with return. They both seem to “show something,” but under the hood they do completely different jobs.
Think of it this way: print is like a flashlight that lights up the moment. return is like an electrical outlet—it gives you power you can use again and again.
What print Really Does
When you call print, Python pushes text to your console or terminal. That’s all. Under the hood, the function still returns None.
def greet():
print("Hello, world!")
result = greet()
print(result) # None
The greet() function lights up the screen with “Hello, world!” but leaves result empty-handed.
print is communication with you, the human. Once it’s shown, it’s gone.
What return Really Does
return hands a value back to the caller. That value can be stored, passed into another function, or reused later.
def make_greeting():
return "Hello, world!"
result = make_greeting()
print(result) # Hello, world!
Here, make_greeting() doesn’t print anything itself. It gives back a string, and now you get to decide what to do with it—print it, write it to a file, or pass it around in your program.
Why the Confusion Happens
A big culprit is the interactive shell (IDLE, Jupyter, REPL). In those environments, returned values are automatically echoed to the screen.
def add(x, y):
return x + y
add(2, 3) # shows 5 in the shell
Switch to print instead of return and it looks the same:
def add(x, y):
print(x + y)
add(2, 3) # prints 5, but returns None
But the illusion breaks as soon as you reuse the result:
result = add(2, 3)
print(result + 10) # TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
That’s because result is None.
Print for Debugging: Why It’s Handy
print isn’t useless—it’s a quick and dirty debugging tool. Drop it into your code to see what a variable looks like at a certain point in time.
def calculate_total(prices):
total = sum(prices)
print("DEBUG:", total) # snapshot without affecting return
return total
You wouldn’t keep these in production code, but when you’re learning (or chasing a bug), print is a cheap flashlight.
Practical Rule of Thumb
- Use
printwhen you want to peek at what’s happening right now. - Use
returnwhen your function should produce a result that other code depends on.
Or:
-
print= talking out loud. -
return= handing over a written note that can be acted on.
A Real-World Example
Imagine writing a function to calculate sales tax:
def calculate_tax(price):
tax = price * 0.07
print(tax)
This looks fine in testing—numbers appear on screen. But when you integrate it:
total = 100 + calculate_tax(100)
It crashes, because calculate_tax returns None.
The fix?
def calculate_tax(price):
return price * 0.07
Now you can do this:
total = 100 + calculate_tax(100)
print(total) # 107.0
Takeaways to Keep in Your Pocket
Mastering this distinction is a turning point in your coding journey. It’s how you go from writing scripts that only talk to you, to building powerful, reusable functions that talk to each other.
Remember:
-
printis for you. -
returnis for the program.
Once that clicks, you’ve unlocked one of Python’s most important mental shifts.
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
Top comments (0)