Работа с файлами: JSON и CSV: вопросы для собеседования (часть 4)
Чтение и запись CSV, парсинг JSON, контекстный менеджер with open — повседневные задачи аналитика. На собеседовании могут попросить прочитать CSV без pandas, распарсить вложенный JSON или объяснить разницу между json.load и json.loads. Эти навыки показывают, что кандидат не привязан к одной библиотеке.
Вопросы 16–20 из 20
16У вас есть объект `rows` (например, список словарей). Как корректно сохранить его в файл `result.json` средствами стандартной библиотеки?
A`with open('result.json', 'w', encoding='utf-8') as f: f.write(rows)`: запись объекта напрямую
B`with open('result.json', 'w', encoding='utf-8') as f: f.write(json.loads(rows))`: через `json.loads`
C`with open('result.json', 'w', encoding='utf-8') as f: f.write(json.dumps(rows))`: через `json.dumps`
D`with open('result.json', 'w', encoding='utf-8') as f: json.dumps(f, rows)`: передача файла первым
Ответ: `json.dumps()` делает строку JSON, которую затем можно записать в файл через `f.write()`.
Чтобы сохранить Python-объект в JSON-файл, сначала сериализуйте его в строку через `json.dumps(rows)`, а затем запишите строку в файл, открытый в режиме `w`. Метод `f.write()` ожидает строку, поэтому передавать ему сам объект `rows` нельзя. `json.loads` делает обратное — парсит строку в объект, поэтому в этой задаче неприменим. Альтернатива — использовать `json.dump(rows, f)`, который сериализует и пишет в один шаг.
Подробный разбор → 17В коде `with open("out.txt", "w", encoding="utf-8") as f: n = f.write("OK")` чему будет равна `n`?
AКоличество записанных символов: для вызова `f.write("OK")` это значение равно `2`
BОбъект файла `f`, чтобы можно было продолжить запись цепочкой вызовов `f.write(...)`
CСама записанная строка `"OK"`, как при возврате значения из встроенной функции `print`
DБулево `True`, если запись прошла без ошибок и буфер был сброшен на диск автоматически
Ответ: Метод `f.write(...)` возвращает количество записанных символов.
Метод `f.write(text)` записывает текст в файл и возвращает количество записанных символов. Это полезно, когда нужно быстро проверить, что запись действительно произошла. В примере `f.write("OK")` запишет два символа, поэтому `n` будет равна 2.
Подробный разбор → 18В файле `events.json` лежит JSON-текст. Как корректно получить Python-объект из этого файла?
A`obj = json.dumps(open('events.json', 'r', encoding='utf-8'))`: `dumps` сериализует объект в строку
B`with open('events.json', 'r', encoding='utf-8') as f: obj = json.loads(f.read())`: читаем текст и парсим
C`obj = json.loads(open('events.json', 'r', encoding='utf-8'))`: `loads` ждёт строку, а не файловый объект
D`with open('events.json', 'w', encoding='utf-8') as f: obj = json.loads(f.read())`: открытие в `w` стирает файл
Ответ: Сначала читаем текст из файла, затем разбираем его через `json.loads()`.
`json.loads()` ожидает строку с JSON-текстом. Поэтому открываем файл в режиме чтения `r`, забираем содержимое через `f.read()`, и только потом вызываем `json.loads(...)`. Контекстный менеджер `with` гарантирует закрытие файла. Вариант с `json.dumps` неверен: эта функция, наоборот, превращает Python-объект в строку. Открытие в режиме `w` уничтожит исходный файл.
Подробный разбор → 19Вы сериализуете объект в JSON и хотите, чтобы кириллица в результате была читаемой, а не в виде `\uXXXX`. Какой вызов лучше?
A`json.dumps(obj)` без дополнительных параметров для стандартной сериализации
B`json.loads(obj, ensure_ascii=False)` для чтения JSON с поддержкой не-ASCII
C`json.dumps(obj, ensure_ascii=True)` для гарантии ASCII в результирующей строке
D`json.dumps(obj, ensure_ascii=False)` для сохранения кириллицы как есть в строке
Ответ: Параметр `ensure_ascii=False` сохраняет не-ASCII символы как есть.
По умолчанию `json.dumps(obj)` часто экранирует не-ASCII символы (кириллицу) в виде последовательностей вроде `\uXXXX`. Если вы хотите получить читаемый JSON, используйте `json.dumps(obj, ensure_ascii=False)`. При записи в файл дополнительно важно открыть его с `encoding="utf-8"`, чтобы текст был сохранён корректно.
Подробный разбор → 20Почему при чтении CSV через модуль `csv` часто пишут `open("data.csv", "r", encoding="utf-8", newline="")`?
AЧтобы автоматически преобразовывать все числовые значения в `int` и `float` при чтении из файла
BЧтобы модуль `csv` корректно обрабатывал переводы строк и не создавал лишних пустых строк или сдвигов
CЧтобы `csv.reader` автоматически пропускал первую строку файла, считая её строкой заголовка таблицы
DЧтобы включить режим добавления данных в конец файла без перезаписи прежнего содержимого, как `mode="a"`
Ответ: Параметр `newline=""` помогает модулю `csv` правильно обрабатывать концы строк независимо от платформы.
Модуль `csv` сам обрабатывает символы перевода строки внутри значений и между записями, поэтому ожидает, что файл откроют с `newline=""`. Иначе на разных платформах (Windows/Linux) возможны лишние пустые строки или некорректное разбиение многострочных полей в кавычках. Параметр `encoding="utf-8"` нужен отдельно — чтобы одинаково читать файлы с не-ASCII символами. Параметр `newline=""` не отвечает ни за пропуск заголовка (это делает `next(reader)` или `csv.DictReader`), ни за приведение типов, ни за режим записи.
Подробный разбор →