Класс FileHandler в Python: инкапсуляция операций с файлами
Классы для работы с файлами в Python: обзор и реализация
Python предоставляет встроенные средства для работы с файлами, однако для удобства и повторного использования часто создают собственный класс-оболочку. Основное преимущество такого класса - инкапсуляция логики открытия, закрытия и обработки ошибок. Рассмотрим несколько вариантов реализации.
Как создать класс с контекстным менеджером для безопасной работы с файлами?
Наиболее эффективное решение - класс, реализующий протокол контекстного менеджера (методы __enter__ и __exit__). Это гарантирует закрытие файла даже при исключениях. Пример:
class FileHandler:
def __init__(self, filename, mode='r', encoding='utf-8'):
self.filename = filename
self.mode = mode
self.encoding = encoding
self.file = None
def __enter__(self):
try:
self.file = open(self.filename, self.mode, encoding=self.encoding)
except FileNotFoundError as e:
print(f'Ошибка: файл {self.filename} не найден')
raise e
except PermissionError as e:
print(f'Ошибка доступа к файлу {self.filename}')
raise e
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
return False
def read(self):
return self.file.read()
def write(self, data):
self.file.write(data)
def readlines(self):
return self.file.readlines()
def writelines(self, lines):
self.file.writelines(lines)
def close(self):
if self.file:
self.file.close()
ввод программ на python (ввод данных в программе python)
Использование: with FileHandler('data.txt', 'r') as fh: content = fh.read()
Вариант: простой класс с методами open/close (без контекстного менеджера)
Этот подход подходит для случаев, когда требуется явное управление жизненным циклом файла, например, в длительных сессиях. Класс предоставляет методы open() и close(), и пользователь сам должен вызвать close().
class SimpleFileHandler:
def __init__(self, filename, mode='r'):
self.filename = filename
self.mode = mode
self.file = None
def open(self):
self.file = open(self.filename, self.mode)
return self.file
def close(self):
if self.file:
self.file.close()
self.file = None
Python file io (ввод-вывод файлов в python)
Цель: минимальный контроль, например, для чтения большого файла с периодическими паузами.
Вариант: класс с использованием декоратора @contextmanager из contextlib
Более лаконичная реализация контекстного менеджера через генератор.
from contextlib import contextmanager
@contextmanager
def file_handler(filename, mode='r'):
try:
file = open(filename, mode)
yield file
finally:
file.close()
Python temp files (временные файлы в python)
Используется как with file_handler('file.txt') as f: ...
Случаи использования: когда нужен простой контекст без создания полноценного класса.
Вариант: класс для работы с бинарными файлами и разными кодировками
Расширяет базовый класс поддержкой бинарных режимов ('rb', 'wb') и явного указания кодировки.
class BinaryFileHandler:
def __init__(self, filename, mode='rb'):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
return self
def __exit__(self, *args):
if self.file:
self.file.close()
def read_bytes(self, size=-1):
return self.file.read(size)
def write_bytes(self, data):
self.file.write(data)
Python index files (индексация файлов в python)
Применение: работа с изображениями, архивами.
Вариант: класс-адаптер для работы с CSV файлами
Класс, который сочетает работу с файлом и встроенным модулем csv.
import csv
class CSVHandler:
def __init__(self, filename, mode='r', delimiter=',', encoding='utf-8'):
self.filename = filename
self.mode = mode
self.delimiter = delimiter
self.encoding = encoding
self.file = None
self.reader = None
self.writer = None
def __enter__(self):
self.file = open(self.filename, self.mode, newline='', encoding=self.encoding)
if 'r' in self.mode:
self.reader = csv.reader(self.file, delimiter=self.delimiter)
elif 'w' in self.mode or 'a' in self.mode:
self.writer = csv.writer(self.file, delimiter=self.delimiter)
return self
def __exit__(self, *args):
if self.file:
self.file.close()
def read_rows(self):
return list(self.reader)
def write_rows(self, rows):
self.writer.writerows(rows)
Используется для импорта/экспорта данных.
Расширенные примеры использования класса FileHandler
Пример 1: Построчное чтение с фильтрацией
with FileHandler('data.txt', 'r') as fh:
for line in fh:
if line.strip():
print(line.strip())
Первая строка Вторая строка ...
Пояснение: итерация по объекту FileHandler возможна благодаря тому, что файл открыт. Используется фильтрация пустых строк.
Пример 2: Копирование файла с буферизацией
with FileHandler('source.txt', 'rb') as src, FileHandler('dest.txt', 'wb') as dst:
while True:
chunk = src.read_bytes(1024)
if not chunk:
break
dst.write_bytes(chunk)
(файл скопирован без вывода)
Пояснение: копирование большими блоками для эффективности. Используется бинарный режим.
Пример 3: Наследование для JSONHandler
import json
class JSONHandler(FileHandler):
def read_json(self):
return json.load(self.file)
def write_json(self, obj):
json.dump(obj, self.file, ensure_ascii=False, indent=2)
data = {"name": "Alice", "age": 30}
with JSONHandler('data.json', 'w') as jh:
jh.write_json(data)
# Файл data.json создан с отступами
Пояснение: наследование позволяет расширить функциональность базового класса для конкретных форматов.
Пример 4: Обработка исключений в контексте
try:
with FileHandler('missing.txt', 'r') as fh:
content = fh.read()
except FileNotFoundError as e:
print('Файл не найден')
Файл не найден
Пояснение: класс пробрасывает исключение, но его можно обработать снаружи.
Пример 5: Работа с большим файлом через генератор
def read_large_file(filename):
with FileHandler(filename, 'r') as fh:
for line in fh:
yield line
for line in read_large_file('huge.txt'):
process(line)
(обработка без загрузки в память)
Пояснение: класс FileHandler поддерживает итерацию, что позволяет эффективно обрабатывать большие файлы.