except Exception as e: print(e) is the most common way to lose a bug. The message survives; the traceback, which says which function and which line, is thrown away. When you catch an error and carry on, keep the trace.
Before
def parse_price(text): return float(text.strip("£")) def total(prices): return sum(parse_price(p) for p in prices) try: total(["£4.99", "£12.50", "free"]) except ValueError as e: print("error:", e)
error: could not convert string to float: 'free'
Fine here, where the code is ten lines long. In a real program you now have to work out which of a dozen float() calls produced it.
After
traceback.print_exc() prints the same full trace Python would have shown, and the program carries on:
import sys, traceback def parse_price(text): return float(text.strip("£")) def total(prices): return sum(parse_price(p) for p in prices) try: total(["£4.99", "£12.50", "free"]) except ValueError: traceback.print_exc(file=sys.stdout) # the full trace; the program carries on print("still running")
Traceback (most recent call last):
File "prices.py", line 10, in <module>
total(["£4.99", "£12.50", "free"])
File "prices.py", line 7, in total
return sum(parse_price(p) for p in prices)
File "prices.py", line 7, in <genexpr>
return sum(parse_price(p) for p in prices)
File "prices.py", line 4, in parse_price
return float(text.strip("£"))
ValueError: could not convert string to float: 'free'
still runningNow it says where: total called parse_price, and parse_price failed on line 4. (The file names differ in the browser; the chain of calls is the same.) Without file=sys.stdout the trace goes to stderr, where Python prints its own errors.
In code that logs
With logging, log.exception("...") inside an except block writes your message plus the full traceback at error level. That's the version to reach for in anything that runs unattended.
Why it works
The exception object carries its traceback in e.__traceback__. print(e) only asks for the message. The traceback module turns it into the familiar text; traceback.format_exc() gives you the same text as a string, for storing or sending.
When not to use it
If an error is expected and handled, like a user typing a word where a number goes, a friendly message is right and a traceback is noise. Keep full traces for the errors you didn't plan for. And a bare except: that swallows everything is its own bug: catch the exceptions you mean, as covered in Errors & Exceptions.