ProgrammingBackend Developer

How is file system handling structured in Python? What are the ways to open, read, and write files, and what are their fundamental differences?

Pass interviews with Hintsage AI assistant

Answer.

Working with the file system is one of the basic tasks in programming with Python. Historically, Python provides a simple and intuitive syntax for file manipulation, which has helped it become a popular language for automation tasks, data processing, and web development.

History of the Question

In early versions of Python, developers accessed the file system using the built-in function open(). With the release of Python 2.5, the context manager protocol was introduced, allowing safe resource management using the with statement, which reduced resource leaks and errors when dealing with files.

Problem

Without a proper approach to file handling, possible issues include:

  • resource leaks from not closing files;
  • data encoding errors;
  • data corruption from improper management of file access modes (reading, writing, appending, binary mode, etc.);
  • problems when handling large files due to loading them fully into memory.

Solution

Modern, correct file handling in Python uses the context manager — the with open() structure:

with open('data.txt', 'r', encoding='utf-8') as file: data = file.read()

This ensures that the file closes automatically, even if an error occurs. To write, the mode 'w' is used, for appending — 'a', and for working with binary data — 'rb', 'wb', etc. For reading large files line by line, it's better to use iteration:

with open('big_data.txt', 'r', encoding='utf-8') as file: for line in file: process(line)

Key features:

  • Support for different operation modes ('r', 'w', 'a', 'b', '+').
  • It is recommended to always explicitly specify the encoding when working with text files.
  • Working with large files is optimal through line-by-line reading rather than using read() fully.

Tricky Questions.

Why use a context manager (with) when opening a file if one can just call file.close()?

Answer: The context manager ensures that the file is closed even if an exception occurs. Manually calling close() is often forgotten, especially when dealing with complex logic or error blocks, leading to resource leaks.

Code example:

try: file = open('data.txt', 'r') data = file.read() finally: file.close()

This approach is more cumbersome than using with open().



**Can you write data to a file opened only in 'r' mode?**

Answer: No, if the file is opened in 'r' mode, writing is not possible — calling write methods (`write`, `writelines`) will raise an exception `io.UnsupportedOperation`. For writing, use 'w', 'a', or 'r+'.

**What happens when opening a nonexistent file in 'r' mode?**

Answer: A `FileNotFoundError` exception will occur. To create a new file, use 'w' (the file will be created if it does not exist), or 'a' (append), or handle the exception.

# Common Mistakes and Antipatterns
- Opening files without explicitly closing them (`file = open(...); ...; file.close()`).
- Not specifying the encoding when working with unicode data.
- Using full read (`read()`) which consumes all memory on large files.

# Real-Life Example
## Negative Case

A developer opens several files without context managers and forgets to close one of them, resulting in a "Too many open files" error on the server.

**Pros:**
- Quick implementation, less code.

**Cons:**
- Descriptor leaks, application crashes in production.
- Potential data loss.

## Positive Case

Using `with open()` for each file, explicitly specifying encoding, processing large files line by line.

**Pros:**
- Reliability, automatic resource release.
- Easy to read, safe to maintain.

**Cons:**
- Requires a bit more initial discipline and knowledge of the syntax.