Работа с форматами файлов: CSV, JSON и TXT
Модуль csv, json.load/dump и безопасная кодировка текста для инструментов агента.
«Работа с форматами файлов: CSV, JSON и TXT» — бесплатный урок AI Agents на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.
Три наиболее распространённых формата файлов агентов
Агенты постоянно читают и записывают файлы в трёх форматах: CSV для табличных данных, JSON для структурированных объектов и обычный текст для журналов, подсказок и отчётов. Для каждого формата нужны свои правила разбора, обработка особых случаев и рекомендации. Python отлично поддерживает все три формата из стандартной библиотеки.
import csv
import json
from pathlib import Path
# Detect format from extension
def read_data_file(file_path):
path = Path(file_path)
if path.suffix == '.csv':
return read_csv(path)
elif path.suffix == '.json':
return read_json(path)
elif path.suffix == '.txt':
return path.read_text(encoding='utf-8')
else:
raise ValueError(f'Unsupported format: {path.suffix}')csv.reader — базовый разбор CSV
csv.reader разбирает CSV-файл построчно, возвращая каждую строку в виде списка строк. Он корректно обрабатывает поля в кавычках, встроенные запятые и символы новой строки внутри значений в кавычках — в отличие от ручного разделения по запятым, которое не справляется с особыми случаями.
import csv
with open('sales.csv', 'w', newline='') as f:
f.write('product,qty,price\nWidget,3,9.99\nGadget,1,19.99\n')
with open('sales.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.reader(f)
header = next(reader)
print('Columns:', header)
for row in reader:
product = row[0]
quantity = int(row[1])
price = float(row[2])
print(f'{product}: {quantity} units at ${price}')csv.DictReader — строка в виде словаря
csv.DictReader считывает каждую строку как OrderedDict (или обычный словарь в Python 3.8 и более поздних версиях), используя заголовки столбцов в качестве ключей. С таким представлением работать гораздо удобнее, чем с позиционной индексацией: код остаётся понятным, даже если порядок столбцов изменится.
import csv
with open('employees.csv', 'w', newline='') as f:
f.write('name,department,salary\nAlice,Eng,95000\nBob,Sales,70000\n')
with open('employees.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
print('Fields:', reader.fieldnames)
total_salary = 0
for row in reader:
name = row['name']
department = row['department']
salary = float(row['salary'])
total_salary += salary
print(f'{name} ({department}): ${salary:,.2f}')
print(f'Total payroll: ${total_salary:,.2f}')csv.writer и DictWriter — запись CSV
Используйте csv.writer, чтобы записывать строки в виде списков, или csv.DictWriter, чтобы записывать строки в виде словарей. При открытии файла всегда передавайте newline='' — модуль csv сам обрабатывает окончания строк, предотвращая появление двойных символов новой строки в Windows.
import csv
results = [
{'task_id': 'T001', 'status': 'completed', 'duration_s': 12.5},
{'task_id': 'T002', 'status': 'failed', 'duration_s': 3.1},
{'task_id': 'T003', 'status': 'completed', 'duration_s': 45.8},
]
fieldnames = ['task_id', 'status', 'duration_s']
with open('task_results.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader() # write column names
writer.writerows(results)
print('Wrote task_results.csv')json.load() и json.dump() — операции ввода-вывода с файлами
Используйте json.load(file), чтобы разобрать JSON-файл, и json.dump(obj, file), чтобы записать его. Эти функции работают с объектами файлов. Для строк используйте json.loads(string) и json.dumps(obj). Для удобного чтения вывода всегда используйте indent=2.
import json
with open('config.json', 'w', encoding='utf-8') as f:
json.dump({'api_url': 'https://api.example.com', 'timeout': 15}, f)
with open('config.json', 'r', encoding='utf-8') as f:
config = json.load(f)
print('API URL:', config.get('api_url'))
print('Timeout:', config.get('timeout', 30))
output_data = {
'run_id': 'abc123',
'items': [1, 2, 3],
'meta': {'agent': 'v2', 'model': 'gpt-4o'}
}
with open('output.json', 'w', encoding='utf-8') as f:
json.dump(
output_data, f,
indent=2,
ensure_ascii=False
)
print('Written output.json')Обработка ошибок разбора JSON
Некорректные JSON-файлы часто встречаются в конвейерах агентов: причиной могут быть незавершённая запись, оборванная загрузка или проблемы с кодировкой. Всегда оборачивайте json.load() в конструкцию обработки исключений и добавляйте в понятные сообщения об ошибках путь к файлу, чтобы упростить отладку.
import json
from pathlib import Path
def safe_load_json(file_path):
path = Path(file_path)
try:
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
except json.JSONDecodeError as e:
print(f'Invalid JSON in {path}: line {e.lineno}, col {e.colno}')
print(f' Error: {e.msg}')
# Show the problem area
content = path.read_text(encoding='utf-8')
lines = content.split('\n')
if e.lineno <= len(lines):
print(f' Content: {lines[e.lineno-1][:80]}')
return None
except FileNotFoundError:
print(f'File not found: {path}')
return None
# --- demo ---
Path('good.json').write_text('{"model": "gpt-4o"}', encoding='utf-8')
Path('bad.json').write_text('{"model": "gpt-4o", }', encoding='utf-8')
print('Loading good.json:', safe_load_json('good.json'))
print('Loading bad.json:', safe_load_json('bad.json'))
Чтение формата JSONL (JSON Lines)
Многие API искусственного интеллекта и конвейеры обработки данных используют JSONL (JSON Lines) — один объект JSON в каждой строке. Этот формат поддерживает потоковую обработку и позволяет легко обрабатывать данные построчно, не загружая весь файл в память. Каждая строка представляет собой полный самостоятельный объект JSON.
import json
with open('events.jsonl', 'w', encoding='utf-8') as f:
f.write('{"event": "start"}\n{"event": "stop"}\nnot json\n')
results = []
with open('events.jsonl', 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
event = json.loads(line)
results.append(event)
except json.JSONDecodeError as e:
print(f'Bad JSON on line {line_num}: {e}')
print(f'Loaded {len(results)} events')
with open('output.jsonl', 'w', encoding='utf-8') as f:
for record in results:
f.write(json.dumps(record, ensure_ascii=False) + '\n')Чтение обычных текстовых файлов
Обычный текст — самый простой формат: журналы, подсказки, отчёты и файлы конфигурации. Считайте весь файл с помощью .read() или обрабатывайте его построчно. Для больших файлов всегда используйте построчный подход, чтобы сохранить постоянное потребление памяти.
from pathlib import Path
Path('system_prompt.txt').write_text('You are a helpful agent.', encoding='utf-8')
with open('agent.log', 'w', encoding='utf-8') as f:
f.write('INFO: boot\nERROR: disk full\nCRITICAL: crash\nINFO: recovered\n')
prompt = Path('system_prompt.txt').read_text(encoding='utf-8')
print(f'Prompt length: {len(prompt)} characters')
error_lines = []
with open('agent.log', 'r', encoding='utf-8') as f:
for line in f:
line = line.rstrip()
if not line:
continue
if 'ERROR' in line or 'CRITICAL' in line:
error_lines.append(line)
print(f'Found {len(error_lines)} error lines')
with open('summary.txt', 'w', encoding='utf-8') as f:
f.write('Agent Run Summary\n')
f.write('=' * 40 + '\n')
for error in error_lines[:10]:
f.write(f' {error}\n')
print('Summary written')Обработка BOM (маркера порядка байтов)
Файлы, экспортированные из Excel или инструментов Windows, часто начинаются с BOM (маркера порядка байтов) — невидимого символа \ufeff. Если его не обработать, он искажает имя первого поля при разборе CSV. Используйте encoding='utf-8-sig', чтобы автоматически удалить его.
import csv
with open('windows_export.csv', 'wb') as f:
f.write('name,email,age\nAlice,alice@x.com,30\n'.encode('utf-8'))
with open('file.txt', 'wb') as f:
f.write(b'\xef\xbb\xbfhello')
with open('windows_export.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
first = next(reader)
print(list(first.keys()))
with open('windows_export.csv', 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f)
first = next(reader)
print(list(first.keys()))
content = open('file.txt', 'rb').read()
if content.startswith(b'\xef\xbb\xbf'):
content = content[3:]
text = content.decode('utf-8')
print('Decoded:', text)Обработка ошибок кодировки
При чтении файлов из неизвестных источников ошибки кодировки встречаются часто. Параметр errors функции open() определяет поведение: 'replace' заменяет некорректные символы на ?, 'ignore' удаляет их, а 'backslashreplace' экранирует их. Для строгой проверки используйте 'strict' (значение по умолчанию).
from pathlib import Path
def read_with_fallback(file_path):
path = Path(file_path)
# Try UTF-8 first
try:
return path.read_text(encoding='utf-8')
except UnicodeDecodeError:
pass
# Try Latin-1 (handles most European files)
try:
return path.read_text(encoding='latin-1')
except UnicodeDecodeError:
pass
# Last resort: replace bad characters
text = path.read_text(encoding='utf-8', errors='replace')
print(f'Warning: {path.name} had encoding errors (chars replaced)')
return text
# --- demo ---
Path('notes_utf8.txt').write_text('Notes: café, naïve, résumé', encoding='utf-8')
text = read_with_fallback('notes_utf8.txt')
print(f'Read {len(text)} chars: {text!r}')
Обработка некорректных CSV-файлов
В реальных CSV-файлах встречаются разные проблемы: лишние запятые, пропущенные поля, непоследовательное использование кавычек или смешанные разделители. Используйте параметры quoting и error_bad_lines, а обработку строк заключайте в конструкцию обработки исключений, чтобы корректно пропускать ошибочные строки.
import csv
with open('messy_data.csv', 'w', newline='') as f:
f.write('name,email,score\nAlice,alice@x.com,88\nBob,,90\nCarol,carol@x.com,notanumber\n')
valid_rows = []
error_count = 0
with open('messy_data.csv', 'r', encoding='utf-8', newline='') as f:
reader = csv.DictReader(f)
expected_fields = {'name', 'email', 'score'}
for line_num, row in enumerate(reader, start=2):
try:
if not all(row.get(f, '').strip() for f in expected_fields):
raise ValueError(f'Missing required field in row {line_num}')
score = float(row['score'])
valid_rows.append({
'name': row['name'].strip(),
'email': row['email'].strip().lower(),
'score': score
})
except (ValueError, KeyError) as e:
error_count += 1
print(f'Skipping row {line_num}: {e}')
print(f'Valid: {len(valid_rows)}, Errors: {error_count}')Быстрая проверка: CSV DictReader и reader
Проверьте, насколько хорошо Вы поняли параметры разбора CSV.
Повторение работы с форматами файлов
Теперь Вы можете разбирать и записывать все основные форматы файлов агентов:
- CSV: используйте
csv.DictReaderдля строк-словарей иcsv.DictWriterдля вывода; при открытии всегда указывайтеnewline='' - JSON: используйте
json.load(f)для разбора иjson.dump(obj, f, indent=2)для записи; обрабатывайтеJSONDecodeError - JSONL: считывайте и разбирайте каждую строку с помощью
json.loads(line); этот формат отлично подходит для потоковой обработки данных - Обычный текст: используйте
.read()для небольших файлов и построчный перебор для больших - BOM: используйте
encoding='utf-8-sig'для файлов, экспортированных из Windows - Ошибки кодировки: попробуйте UTF-8, используйте latin-1 как запасной вариант или укажите
errors='replace'
Часто задаваемые вопросы
Урок «Работа с форматами файлов: CSV, JSON и TXT» бесплатный?
Да — полный текст урока «Работа с форматами файлов: CSV, JSON и TXT» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.
Чему я научусь в уроке «Работа с форматами файлов: CSV, JSON и TXT»?
Модуль csv, json.load/dump и безопасная кодировка текста для инструментов агента. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Agents?
Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Работа с форматами файлов: CSV, JSON и TXT»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Agents?
Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Чтение и запись файлов в контексте агента
- Обход каталогов и поиск файлов
- Работа с форматами файлов: CSV, JSON и TXT
- Безопасные операции с файлами и обработка ошибок