Как правильно изменять файлы в Python: техники и код

Раздел: Работа с файлами -> Файловый ввод-вывод

Основной подход: чтение, изменение, запись

Наиболее универсальный способ редактирования файла в Python состоит из трех шагов: открыть файл в режиме чтения ('r'), прочитать все содержимое, внести изменения в строку или байты, затем открыть тот же файл в режиме записи ('w') и записать новое содержимое. Этот метод подходит для файлов любого объема, если данные полностью помещаются в оперативную память.


with open('example.txt', 'r', encoding='utf-8') as f:
    text = f.read()

text = text.replace('старая_строка', 'новая_строка')

with open('example.txt', 'w', encoding='utf-8') as f:
    f.write(text)

ввод программ на python (ввод данных в программе python)

В примере заменяется одна подстрока на другую. Кодировка указана явно - это позволяет избежать проблем с кириллицей. Если файл очень большой (сотни мегабайт), читать его целиком неэффективно; в таких случаях применяется построчная обработка с записью во временный файл (см. варианты ниже).

Возможные проблемы:

  • Потеря данных при сбое во время записи: если процесс прервется, исходный файл может оказаться пустым. Решение: записывать сначала во временный файл, затем заменять оригинал.
  • Неверная кодировка: использование encoding помогает, но если файл уже открыт в другой кодировке, возникнут ошибки UnicodeDecodeError. Нужно определить кодировку заранее (например, через chardet).
  • Случайная перезапись: режим 'w' обнуляет файл. Если нужно дописать или изменить часть, используйте другие варианты.

Различные варианты редактирования

Как добавить текст в конец файла?

Используется режим 'a' (append). Файл открывается для добавления данных в конец, указатель ставится на последнюю позицию.


with open('log.txt', 'a', encoding='utf-8') as f:
    f.write('Новая запись\n')

Python file io (ввод-вывод файлов в python)

Типичная ошибка: забыть символ новой строки - каждая запись окажется на одной строке. Кодировка должна совпадать с уже имеющейся в файле.


Как вставить строку в середину файла, не перезаписывая его полностью?

Прямой вставки без временного файла не существует. Приходится читать все строки, вставлять нужную и записывать заново.


with open('data.txt', 'r', encoding='utf-8') as f:
    lines = f.readlines()

lines.insert(2, 'Вставленная строка\n')   # вставить после строки с индексом 1

with open('data.txt', 'w', encoding='utf-8') as f:
    f.writelines(lines)

Python temp files (временные файлы в python)

Проблема: при большом количестве строк список lines занимает много памяти. Решение - использовать модуль fileinput (см. примеры ниже).


Как заменить все вхождения слова в файле?

Простой способ - использовать метод str.replace() для всего текста.


with open('text.txt', 'r', encoding='utf-8') as f:
    content = f.read()
content = content.replace('Python', 'Java')
with open('text.txt', 'w', encoding='utf-8') as f:
    f.write(content)

Python index files (индексация файлов в python)

Замена регистрозависимая. Для регистронезависимой замены потребуется регулярное выражение или предварительный поиск. Также метод replace не работает с шаблонами - только с фиксированными строками.


Как изменить файл без создания временного файла, используя режим 'r+'?

Режим 'r+' позволяет читать и писать, но запись начинается с текущей позиции указателя, что может привести к наложению данных. Для замены одинаковой длины это подходит, для разной - нет.


with open('test.bin', 'r+b') as f:
    data = f.read()
    # заменить байты той же длины
    data = data.replace(b'old', b'new')
    f.seek(0)
    f.write(data)
    f.truncate()

File python class (класс для работы с файлами в python)

Ошибки: неверное позиционирование указателя; забытый вызов truncate(), если новые данные короче старых - в конце останется мусор.


Как редактировать бинарные файлы (например, изображения)?

Открывать в режиме 'rb+', изменять конкретные байты, зная их смещение. Часто используется модуль struct для упаковки/распаковки чисел.


import struct

with open('data.bin', 'r+b') as f:
    f.seek(4)  # смещение 4 байта
    value = struct.unpack('i', f.read(4))[0]
    value += 1
    f.seek(4)
    f.write(struct.pack('i', value))

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

- Python copy file (копирование файла в python)
- Python log file (логирование в файл в python)
- Python file methods (методы работы с файлами в python)

Расширенные примеры с пояснениями

1. Замена нескольких строк с помощью временного файла (безопасный способ)

Пример

import tempfile
import shutil

source = 'large_file.txt'
temp = tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8')

with open(source, 'r', encoding='utf-8') as inf:
    for line in inf:
        if 'привет' in line:
            line = line.replace('привет', 'здравствуйте')
        temp.write(line)

temp.close()
shutil.move(temp.name, source)

Пояснение: файл обрабатывается построчно, поэтому память не перегружается. Временный файл создается в системной папке, после обработки заменяет оригинал. Если во время работы возникнет ошибка, исходный файл останется нетронутым (временный будет удален автоматически).

Файл large_file.txt будет изменен, но только после успешного завершения скрипта.

2. Использование модуля fileinput для редактирования «на месте»

Пример

import fileinput

for line in fileinput.input('config.ini', inplace=True, encoding='utf-8'):
    print(line.replace('DEBUG', 'INFO'), end='')

Пояснение: fileinput перенаправляет стандартный вывод в файл. Каждая строка выводится через print (по умолчанию добавляет перевод строки; end='' отключает его). Параметр inplace=True заставляет модуль создавать резервную копию (если нужно, можно задать суффикс.

Файл config.ini будет изменен без создания временного файла вручную. Старая версия сохраняется с расширением .bak (если не указан параметр backup).

3. Редактирование с помощью pathlib (для простых замен)

Пример

from pathlib import Path

file = Path('notes.txt')
text = file.read_text(encoding='utf-8')
text = text.replace('неправильно', 'правильно')
file.write_text(text, encoding='utf-8')

Пояснение: методы read_text() и write_text() скрывают открытие/закрытие файла. Удобно для небольших файлов. Аналогично для бинарных: read_bytes() и write_bytes().

Файл notes.txt будет перезаписан.

4. Замена с помощью регулярных выражений (гибкая замена)

Пример

import re

with open('mixed.txt', 'r', encoding='utf-8') as f:
    content = f.read()

pattern = r'\b(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\b'  # IP-адрес
replacement = r'\1-\2-\3-\4'
new_content = re.sub(pattern, replacement, content)

with open('mixed.txt', 'w', encoding='utf-8') as f:
    f.write(new_content)

Пояснение: регулярное выражение ищет все IP-адреса и заменяет точки на дефисы. re.sub обрабатывает весь текст. Важно экранировать обратные ссылки в строке замены.

Пример: '192.168.0.1' станет '192-168-0-1'.

5. Редактирование CSV-файла (изменение столбцов)

Пример

import csv

rows = []
with open('data.csv', 'r', newline='', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        row['age'] = str(int(row['age']) + 1)  # увеличить возраст на 1
        rows.append(row)

with open('data.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.DictWriter(f, fieldnames=reader.fieldnames)
    writer.writeheader()
    writer.writerows(rows)

Пояснение: DictReader преобразует строки в словари по заголовкам. Изменяем нужное поле, затем записываем все строки обратно. Модуль csv автоматически обрабатывает кавычки и разделители.

Возраст каждого человека увеличится на 1. Файл перезаписан.

6. Вставка строки после определенного маркера

Пример

marker = '# END'
insert_line = 'Новый параметр = значение\n'

with open('settings.ini', 'r', encoding='utf-8') as f:
    lines = f.readlines()

for i, line in enumerate(lines):
    if line.strip() == marker:
        lines.insert(i+1, insert_line)
        break

with open('settings.ini', 'w', encoding='utf-8') as f:
    f.writelines(lines)

Пояснение: ищется строка, совпадающая с маркером, после нее вставляется новая строка. Если маркер не найден, файл останется без изменений (для надежности можно добавить проверку).

В файл settings.ini после строки '# END' добавится новая строка.

Редактирование файла Python - comments

En
Python edit file (python)