#python #json #compression #pickle
#питон #json #сжатие #pickle
Вопрос:
Я хотел бы написать метод, который принимает имя файла в качестве входных данных, затем проверяет, сжат ли файл или нет (gzip, xz / LZMA, нет), а затем проверяет, является ли содержимое файла маринованным объектом python или словарем в кодировке JSON. Цель здесь состоит в том, чтобы предоставить пользователям некоторую гибкость в том, как они хранят / кодируют данные, которые в конечном счете представляют собой просто набор строк…
Каков наиболее разумный способ структурирования этого кода? Должен ли я просто try
открывать файл с каждым из поддерживаемых (de) компрессоров, или есть какой-то лучший способ определить тип файла и вызвать соответствующий open
метод?
Аналогичный вопрос для данных внутри … если не считать попытки json.load()
или pickle.load()
и перехвата исключений, есть ли какой-нибудь более элегантный / эффективный / поддерживаемый способ сделать это?
Я знаю, что могу собрать достаточно логики if-then-else или try-except, чтобы в конечном итоге заставить ее работать, но я достаточно новичок в этом, и я хотел бы, по крайней мере, запросить информацию о том, что может иметь наибольший смысл. Я думаю, в каком-то смысле я спрашиваю, должна ли философия быть
- «проверьте что-нибудь, чтобы выяснить, что это за файл на самом деле, затем вызовите open / load на основе этого ответа»
- в отличие от …
- «перебирайте, пробуйте все, что вы знаете, как обрабатывать, и в конечном итоге используйте то, что не вызывает исключения».
Ответ №1:
Первые шесть байтов файла xz в шестнадцатеричном fd 37 7a 58 5a 00
формате. Первые три байта файла gz являются 1f 8b 08
.
Поток JSON должен начинаться с '{'
или '['
. Файл pickle должен начинаться с кода операции, который сегодня не включает '{'
или '['
, или 'xfd'
или 'x1f'
.
Итак, если в формат pickle не добавлены коды операций, которые перекрываются с JSON или сигнатурами сжатых данных, и если вы знаете, что ваш ввод должен быть одним из этих четырех, а распакованные данные должны быть одним из этих двух, то, похоже, вы можете делать то, что хотите.
Обратите внимание, что декодирование формата pickle эффективно выполняет код Python, поэтому он не считается безопасным. Его не следует использовать с ненадежным создателем.
Взятые из связанного источника, вот коды операций Python 3.8.1 pickle:
'(', ')', '.', '0', '1', '2', 'B', 'C', 'F', 'G', 'I', 'J', 'K', 'L', 'M', 'N',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', ']', 'a', 'b', 'c', 'd', 'e', 'g',
'h', 'i', 'j', 'l', 'o', 'p', 'q', 'r', 's', 't', 'u', '}', 'x80', 'x81',
'x82', 'x83', 'x84', 'x85', 'x86', 'x87', 'x88', 'x89', 'x8a', 'x8b',
'x8c', 'x8d', 'x8e', 'x8f', 'x90', 'x91', 'x92', 'x93', 'x94', 'x95',
'x96', 'x97', 'x98'