Files, I/O, and Exception Handling
This page brings together three topics that frequently appear together:
- How to read input and write output
- How to handle files safely
- How to make your program more robust when errors occur
Standard I/O
The most basic input is input():
name = input("name: ")
age = int(input("age: "))
print(name, age)
For multiple values on one line, typically combine split() and map():
x, y = map(int, input().split())
For more complete reading patterns, see this quick reference:
File Reading and Writing
Reading a text file
The most recommended approach is with open(...), which automatically closes the file:
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
Reading line by line
with open("notes.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.rstrip())
Writing to a file
lines = ["alpha", "beta", "gamma"]
with open("out.txt", "w", encoding="utf-8") as f:
f.write("\n".join(lines))
Common modes:
"r": Read"w": Write, overwrites existing content"a": Append"rb"/"wb": Binary mode
Basic JSON Handling
For structured data, consider the json module first:
import json
data = {"name": "alice", "score": 95}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
Exception Handling
Why handle exceptions
Many errors aren't "code written incorrectly" but rather the runtime environment not meeting expectations:
- File doesn't exist
- User input isn't a number
- Dictionary doesn't have that key
- Network request failed
Don't pretend the program will never error; instead, explicitly handle the exceptions you expect.
try / except / else / finally
try:
value = int(input("number: "))
except ValueError:
print("Please enter an integer")
else:
print("Read successfully", value)
finally:
print("This part always executes")
Only catch exceptions you actually want to handle
Not recommended to start with:
try:
...
except Exception:
...
This swallows many problems that should be exposed. A safer approach is to write specific exception types first:
try:
with open("missing.txt", "r", encoding="utf-8") as f:
print(f.read())
except FileNotFoundError:
print("File does not exist")
raise: actively raising exceptions
When input doesn't meet your constraints, you can raise an error:
def divide(a, b):
if b == 0:
raise ValueError("b cannot be 0")
return a / b
Habits I recommend
- Write all file operations as
with open(..., encoding="utf-8") - Separate "normal logic" and "exception handling" -- don't mix them into one blob
- Catch as specifically as possible; don't blindly use
except Exception - When something should fail, let it fail explicitly; don't swallow exceptions just to "look like there's no error"