File I/O in Python
Working with files is fundamental to most programs. Python provides two complementary approaches: the built-in open() function for low-level file operations, and the modern pathlib.Path class for object-oriented path manipulation.
The open() Function
open(filename, mode, encoding) opens a file and returns a file object:
The close() call is critical โ open file handles consume OS resources. If your code raises an exception before close(), the file stays open. This is why you should almost always use the with statement instead.
File Modes
The mode string controls what operations are allowed:
| Mode | Meaning | Creates file? | Truncates? |
|---|---|---|---|
"r" | Read text (default) | No | No |
"w" | Write text | Yes | Yes |
"a" | Append text | Yes | No |
"x" | Exclusive create | Fails if exists | โ |
"r+" | Read and write | No | No |
"rb" | Read binary | No | No |
"wb" | Write binary | Yes | Yes |
"ab" | Append binary | Yes | No |
The with Statement (Context Manager)
The with statement guarantees the file is closed when the block exits โ even if an exception occurs:
Multiple files in one with statement:
Reading Methods
File objects have several reading methods:
For large files, iterating the file object directly is most efficient โ it reads one line at a time without loading the whole file into memory.
Writing Methods
Encoding
Always specify the encoding explicitly. UTF-8 is the universal choice for modern systems:
pathlib.Path: Modern Path Handling
The pathlib module (Python 3.4+) provides an object-oriented interface for filesystem paths:
Path Interrogation
Common Path Operations
Building Paths Safely
os.path vs pathlib
os.path is the older, string-based approach. pathlib is the modern replacement:
For new code, prefer pathlib. It's more readable, more cross-platform, and has a richer API.
Practical Example: Log Rotation
Knowledge Check
Why is the `with open(...) as f:` pattern preferred over manually calling `f.close()`?
What happens when you open a file with mode `'w'` and the file already exists?
In pathlib, how do you combine path segments into a single Path object?