Работа с файлами в Python — чтение и запись

Коротко

Работа с файлами — базовый навык Python. Аналитик читает CSV, JSON, логи, конфиги и записывает результаты. Ключевая конструкция — with open(...) as f:, которая гарантирует закрытие файла. На собеседованиях спрашивают про режимы открытия (r/w/a), кодировку, контекстный менеджер и отличие от pandas read_csv.

Чтение файла

# Рекомендуемый способ — with (контекстный менеджер)
with open('data.txt', 'r', encoding='utf-8') as f:
    content = f.read()    # весь файл как строка

print(content)

with автоматически закрывает файл, даже если произошла ошибка. Без with нужно вызывать f.close() вручную — легко забыть.

Способы чтения

with open('data.txt', 'r', encoding='utf-8') as f:
    # Весь файл как строка
    content = f.read()

    # Одна строка
    line = f.readline()

    # Все строки как список
    lines = f.readlines()
    # ['строка 1\n', 'строка 2\n', 'строка 3\n']

# Построчно в цикле (самый экономный по памяти)
with open('data.txt', 'r', encoding='utf-8') as f:
    for line in f:
        print(line.strip())  # strip() убирает \n

Для больших файлов — итерация в цикле: файл читается построчно, не загружая весь в память.

Запись в файл

# Перезаписать файл (w — write)
with open('output.txt', 'w', encoding='utf-8') as f:
    f.write('Строка 1\n')
    f.write('Строка 2\n')

# Дописать в конец (a — append)
with open('log.txt', 'a', encoding='utf-8') as f:
    f.write('Новая запись\n')

# Записать список строк
lines = ['Строка 1\n', 'Строка 2\n', 'Строка 3\n']
with open('output.txt', 'w', encoding='utf-8') as f:
    f.writelines(lines)
Режим Описание
'r' Чтение (по умолчанию). Ошибка, если файла нет
'w' Запись. Создаёт файл или перезаписывает существующий
'a' Дополнение. Пишет в конец файла
'x' Создание. Ошибка, если файл уже существует
'rb' Чтение бинарного файла (картинки, архивы)
'wb' Запись бинарного файла

CSV-файлы

Через модуль csv

import csv

# Чтение CSV
with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.reader(f)
    header = next(reader)       # первая строка — заголовок
    for row in reader:
        print(row)              # ['value1', 'value2', ...]

# Чтение как словари
with open('data.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row['name'], row['age'])

# Запись CSV
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['name', 'age', 'city'])      # заголовок
    writer.writerow(['Иван', 28, 'Москва'])
    writer.writerows([                              # несколько строк
        ['Анна', 32, 'Питер'],
        ['Пётр', 25, 'Казань'],
    ])

newline='' при записи CSV — предотвращает двойные переносы строк на Windows.

Через pandas (рекомендуется для аналитики)

import pandas as pd

# Чтение
df = pd.read_csv('data.csv')
df = pd.read_csv('data.csv', sep=';', encoding='cp1251')  # другой разделитель и кодировка

# Запись
df.to_csv('output.csv', index=False, encoding='utf-8')

Для аналитических задач pandas read_csv / to_csv удобнее модуля csv.

JSON-файлы

import json

# Чтение
with open('config.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

# Запись
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

Подробнее — в гайде по JSON в Python.

Кодировка

# UTF-8 — стандарт, всегда указывайте явно
with open('file.txt', 'r', encoding='utf-8') as f:
    content = f.read()

# CP1251 (Windows-1251) — часто встречается в русских CSV
with open('file.csv', 'r', encoding='cp1251') as f:
    content = f.read()

# Определить кодировку автоматически
# pip install chardet
import chardet
with open('unknown.csv', 'rb') as f:
    result = chardet.detect(f.read())
    print(result['encoding'])  # 'utf-8' или 'windows-1251'

Всегда указывайте encoding='utf-8'. Если файл из 1С, Excel на Windows или старой CRM — попробуйте cp1251.

Работа с путями: pathlib

from pathlib import Path

# Создание пути
p = Path('data') / 'reports' / 'march.csv'
print(p)  # data/reports/march.csv

# Проверки
p.exists()        # True/False
p.is_file()       # True/False
p.is_dir()        # True/False

# Информация
p.name            # 'march.csv'
p.stem            # 'march'
p.suffix          # '.csv'
p.parent          # Path('data/reports')

# Чтение / запись
content = p.read_text(encoding='utf-8')
p.write_text('hello', encoding='utf-8')

# Список файлов
for f in Path('data').glob('*.csv'):
    print(f.name)

# Рекурсивный поиск
for f in Path('data').rglob('*.json'):
    print(f)

pathlib — современная замена os.path. Удобнее для формирования путей и поиска файлов.

Практические примеры

Обработка логов

errors = []
with open('app.log', 'r', encoding='utf-8') as f:
    for line in f:
        if 'ERROR' in line:
            errors.append(line.strip())

print(f'Найдено ошибок: {len(errors)}')

Объединение нескольких CSV

from pathlib import Path
import pandas as pd

files = Path('data').glob('orders_*.csv')
dfs = [pd.read_csv(f) for f in files]
df = pd.concat(dfs, ignore_index=True)
df.to_csv('all_orders.csv', index=False)

Конвертация кодировки

with open('old.csv', 'r', encoding='cp1251') as f:
    content = f.read()

with open('new.csv', 'w', encoding='utf-8') as f:
    f.write(content)

Типичные ошибки

Забыли encoding. Без encoding='utf-8' Python использует системную кодировку. На Windows это может быть cp1251 — кириллица будет «кракозябрами» при чтении UTF-8 файла.

Режим 'w' вместо 'a'. open('file.txt', 'w') перезапишет файл. Если нужно дописать — 'a' (append).

Не используют with. Без with файл может остаться открытым при ошибке. with гарантирует закрытие.

Читают большой файл целиком. f.read() загружает весь файл в память. Для файлов в гигабайтах — читайте построчно или чанками.

Вопросы с собеседований

-- Зачем нужен with при работе с файлами? -- with — контекстный менеджер, гарантирует закрытие файла даже при исключении. Без with нужно вручную вызывать f.close().

-- Чем отличается 'r' от 'rb'? -- 'r' — текстовый режим, возвращает строки, обрабатывает переводы строк. 'rb' — бинарный, возвращает bytes, для картинок, архивов, PDF.

-- Как прочитать большой файл, не загружая в память? -- Построчная итерация: for line in f:. Каждая итерация читает одну строку. Для CSV: pd.read_csv('file.csv', chunksize=10000).

-- Чем open + csv отличается от pandas read_csv? -- csv — стандартная библиотека, построчная обработка, минимальный overhead. pandas — загружает в DataFrame, удобен для анализа, но потребляет больше памяти.


Потренируйтесь решать задачи — откройте тренажёр с 1500+ вопросами для подготовки к собеседованиям аналитиков.

FAQ

os.path vs pathlib — что использовать?

pathlib (Python 3.4+) — современный подход, объектно-ориентированный, удобный. os.path — старый, процедурный. Для нового кода — pathlib. Оба работают, но pathlib читабельнее.

Как работать с Excel в Python?

pd.read_excel('file.xlsx') и df.to_excel('file.xlsx'). Для работы без pandas — библиотека openpyxl. Для .xls (старый формат) — xlrd.

Как обработать файл с ошибками кодировки?

open('file.txt', 'r', encoding='utf-8', errors='replace') — заменит невалидные символы на . errors='ignore' — пропустит их. Для определения кодировки — библиотека chardet.

Как тренироваться

Работа с файлами — базовый навык Python. Задачи на Python — в тренажёре Карьерник. Больше вопросов — в разделе с примерами.