Как сделать сохранение данных в python
Взаимодействие с файловой системой позволяет хранить информацию, полученную в результате работы программы. Михаил Свинцов из SkillFactory расскажет о базовой функциональности языка программирования Python для работы с файлами.
Встроенные средства Python
Основа для работы с файлами — built-in функция open()
Начать саму работу с файлом можно с помощью объекта класса io.TextIOWrapper , который возвращается функцией open() . У этого объекта есть несколько атрибутов, через которые можно получить информацию
- name — название файла;
- mode — режим, в котором этот файл открыт;
- closed — возвращает True , если файл был закрыт.
По завершении работы с файлом его необходимо закрыть при помощи метода close()
Однако более pythonic way стиль работы с файлом встроенными средствами заключается в использовании конструкции with .. as .. , которая работает как менеджер создания контекста. Написанный выше пример можно переписать с ее помощью
Главное отличие заключается в том, что python самостоятельно закрывает файл, и разработчику нет необходимости помнить об этом. И бонусом к этому не будут вызваны исключения при открытии файла (например, если файл не существует).
Чтение из файла
При открытии файла в режимах, допускающих чтение, можно использовать несколько подходов.
Для начала можно прочитать файл целиком и все данные, находящиеся в нем, записать в одну строку.
Используя эту функцию с целочисленным аргументом, можно прочитать определенное количество символов.
При этом будут получены только первые 16 символов текста. Важно понимать, что при применении этой функции несколько раз подряд будет считываться часть за частью этого текста — виртуальный курсор будет сдвигаться на считанную часть текста. Его можно сдвинуть на определенную позицию, при необходимости воспользовавшись методом seek() .
Другой способ заключается в считывании файла построчно. Метод readline() считывает строку и, также как и с методом read() , сдвигает курсор — только теперь уже на целую строку. Применение этого метода несколько раз будет приводить к считыванию нескольких строк. Схожий с этим способом, другой метод позволяет прочитать файл целиком, но по строкам, записав их в список. Этот список можно использовать, например, в качестве итерируемого объекта в цикле.
Однако и здесь существует более pythonic way. Он заключается в том, что сам объект io.TextIOWrapper имеет итератор, возвращающий строку за строкой. Благодаря этому нет необходимости считывать файл целиком, сохраняя его в список, а можно динамически по строкам считывать файл. И делать это лаконично.
Запись в файл
Функциональность внесения данных в файл не зависит от режима — добавление данных или перезаписывание файла. В выполнении этой операции также существует несколько подходов.
Самый простой и логичный — использование функции write()
Важно, что в качестве аргумента функции могут быть переданы только строки. Если необходимо записать другого рода информацию, то ее необходимо явно привести к строковому типу, используя методы __str__(self) для объектов или форматированные строки.
Есть возможность записать в файл большой объем данных, если он может быть представлен в виде списка строк.
Здесь есть еще один нюанс, связанный с тем, что функции write() и writelines() автоматически не ставят символ переноса строки, и это разработчику нужно контролировать самостоятельно.
Существует еще один, менее известный, способ, но, возможно, самый удобный из представленных. И как бы не было странно, он заключается в использовании функции print() . Сначала это утверждение может показаться странным, потому что общеизвестно, что с помощью нее происходит вывод в консоль. И это правда. Но если передать в необязательный аргумент file объект типа io.TextIOWrapper , каким и является объект файла, с которым мы работаем, то поток вывода функции print() перенаправляется из консоли в файл.
Сила такого подхода заключается в том, что в print() можно передавать не обязательно строковые аргументы — при необходимости функция сама их преобразует к строковому типу.
На этом знакомство с базовой функциональностью работы с файлами можно закончить. Вместе с этим стоит сказать, что возможности языка Python им не ограничивается. Существует большое количество библиотек, которые позволяют работать с файлами определенных типов, а также допускают более тесное взаимодействие с файловой системой. И в совокупности они предоставляют разработчикам легкий и комфортный способ работы с файлами.
В этом уроке вы узнаете:
- Что означает сериализация и десериализация объекта
- Какие модули вы можете использовать для сериализации объектов в Python
- Какие виды объектов можно сериализовать с помощью pickle модуля Python
- Как использовать pickle модуль Python для сериализации объектных иерархий
- Каковы риски при десериализации объекта из ненадежного источника
Сериализация в Python
Процесс сериализации – это способ преобразования структуры данных в линейную форму, которая может храниться или передаваться по сети.
Сериализация может использоваться в самых разных ситуациях. Одним из наиболее распространенных применений является сохранение состояния нейронной сети после фазы обучения, чтобы вы могли использовать его позже без необходимости повторять обучение.
Python предлагает три различных модуля в стандартной библиотеке, которые позволяют сериализовать и десериализовывать объекты:
Кроме того, Python поддерживает XML , который вы также можете использовать для сериализации объектов.
marshal Модуль является самым старым из трех перечисленных выше. Он существует главным образом для чтения и записи скомпилированного байт-кода модулей Python или .pyc файлов, которые вы получаете, когда интерпретатор импортирует модуль Python. Таким образом, даже если вы можете использовать marshal для сериализации некоторых из ваших объектов, это не рекомендуется.
json Модуль является новейшим из трех. Позволяет работать со стандартными файлами JSON. JSON – это очень удобный и широко используемый формат для обмена данными.
Есть несколько причин выбрать формат JSON : он удобен для чтения и не зависит от языка и легче XML. С помощью json модуля вы можете сериализовать и десериализовать несколько стандартных типов Python:
Модуль Python pickle – это еще один способ сериализации и десериализации объектов в Python. Он отличается от json модуля тем, что сериализует объекты в двоичном формате, что означает, что результат не читается человеком. Тем не менее, он также быстрее и работает со многими другими типами Python, включая ваши пользовательские объекты.
Примечание: С этого момента, вы будете видеть термины pickling и unpickling используется для обозначения сериализации и десериализации с Python pickle модуля.
Итак, у вас есть несколько различных способов сериализации и десериализации объектов в Python. Но какой из них вы должны использовать? Короткий ответ: нет единого решения для всех. Все зависит от вашего варианта использования.
Вот три основных руководства для принятия решения, какой подход использовать:
- Не используйте marshal модуль. Он используется главным образом интерпретатором, и официальная документация предупреждает, что сопровождающие Python могут изменять формат обратно несовместимыми способами.
- json Модуль и XML является хорошим выбором , если вам нужно взаимодействие с различными языками или воспринимаемым форматом.
- Модуль Python pickle – лучший выбор для всех остальных вариантов использования. Если вам не нужен читаемый человеком формат или стандартный совместимый формат, или если вам нужно сериализовать пользовательские объекты, тогда переходите к pickle .
Внутри pickle модуля Python
Модуль Python pickle основном состоит из четырех методов:
- pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
- pickle.dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)
- pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
- pickle.loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
Первые два метода используются во время процесса pickling, а два других используются во время unpickling. Единственная разница между dump() и dumps() заключается в том, что первый создает файл, содержащий результат сериализации, а второй возвращает строку.
Чтобы отличить dumps() от dump() , полезно помнить, что s в конце имени функции стоит символ string . То же самое относится и к load() и loads() : первый читает файл, чтобы начать процесс расслоения, а второй работает со строкой.
Рассмотрим следующий пример. Допустим, у вас есть пользовательский класс example_class с несколькими разными атрибутами, каждый из которых имеет свой тип:
- a_number
- a_string
- a_dictionary
- a_list
- a_tuple
В приведенном ниже примере показано, как создать экземпляр класса и выбрать экземпляр, чтобы получить простую строку. После выбора класса вы можете изменить значение его атрибутов, не затрагивая выбранную строку. Затем вы можете снять выделенную строку в другой переменной, восстановив точную копию ранее выбранного класса:
В приведенном выше примере вы создаете несколько различных объектов и сериализуете их pickle . Это производит единственную строку с сериализованным результатом:
Процесс pickling завершается правильно, сохраняя весь ваш экземпляр в этой строке: b'\x80\x03c__main__\nexample_class\nq\x00)\x81q\x01.' После завершения процесса травления вы изменяете свой исходный объект, устанавливая атрибут a_dict в None .
Наконец, вы открываете строку для совершенно нового экземпляра. То, что вы получаете, является глубокой копией вашей исходной структуры объекта с момента начала процесса pickling.
Форматы протокола pickle модуля
Как уже упоминалось выше, pickle модуль является специфичным для Python, и результат процесса pickling может быть прочитан только другой программой Python. Но даже если вы работаете с Python, важно знать, что pickle модуль эволюционировал со временем.
Это означает, что если вы выбрали объект с определенной версией Python, вы не сможете удалить его с более старой версией. Совместимость зависит от версии протокола, который вы использовали для процесса травления.
В настоящее время существует шесть различных протоколов, которые pickle может использовать . Чем выше версия протокола, тем более поздним должен быть интерпретатор Python для расщепления.
- Протокол версии 0 был первой версией. В отличие от более поздних протоколов, он удобочитаем.
- Протокол версии 1 был первым двоичным форматом.
- Протокол версии 2 был представлен в Python 2.3.
- Протокол версии 3 был добавлен в Python 3.0. Не может быть выбран Python 2.x.
- Протокол версии 4 был добавлен в Python 3.4. Он поддерживает более широкий диапазон размеров и типов объектов и является протоколом по умолчанию, начиная с Python 3.8.
- Протокол версии 5 был добавлен в Python 3.8. Он имеет поддержку внеполосных данных и улучшенную скорость для внутриполосных данных.
Примечание. Более новые версии протокола предлагают больше функций и улучшений, но ограничены более высокими версиями интерпретатора. Обязательно учитывайте это при выборе протокола для использования.
Чтобы определить самый высокий протокол, который поддерживает ваш интерпретатор, вы можете проверить значение pickle.HIGHEST_PROTOCOL атрибута.
Чтобы выбрать конкретный протокол , необходимо указать версию протокола при вызове load() , loads() , dump() или dumps() . Если вы не укажете протокол, ваш интерпретатор будет использовать версию по умолчанию, указанную в pickle.DEFAULT_PROTOCOL атрибуте.
Выбираемые и необратимые типы
Вы уже узнали, что pickle модуль Python может сериализовать гораздо больше типов, чем json модуль. Тем не менее, не все picklable. Список unpicklable объектов включает соединения с базой данных, открытые сетевые сокеты, запущенные потоки и др.
Если вы обнаружите, что столкнулись с unpicklable, то есть несколько вещей, которые вы можете сделать. Первый вариант – использовать стороннюю библиотеку, например dill .
dill Модуль расширяет возможности pickle . Согласно официальной документации , он позволяет сериализовать менее распространенные типы, такие как функции с выходами, вложенные функции , лямбда-выражения и многие другие.
Чтобы проверить этот модуль, вы можете попробовать выбрать lambda функцию:
Если вы попытаетесь запустить эту программу, вы получите исключение, потому что pickle модуль Python не может сериализовать lambda функцию:
Теперь попробуйте заменить pickle модуль Python на, dill чтобы увидеть, есть ли разница:
Если вы запустите этот код, вы увидите, что dill модуль сериализует lambda без возврата ошибки:
Еще одна интересная особенность dill заключается в том, что он может даже сериализовать весь сеанс интерпретатора. Вот пример:>>>
В этом примере вы запускаете интерпретатор, импортируете модуль и определяете lambda функцию вместе с несколькими другими переменными. Затем вы импортируете dill модуль и вызываете dump_session() для сериализации всей сессии.
Если все идет хорошо, вы должны получить test.pkl файл в текущем каталоге:
Теперь вы можете запустить новый экземпляр интерпретатора и загрузить test.pkl файл для восстановления вашего последнего сеанса:>>>
Первое globals().items() утверждение показывает, что интерпретатор находится в исходном состоянии. Это означает, что вам нужно импортировать dill модуль и вызвать load_session() для восстановления сеанса сериализованного интерпретатора.
Примечание. Прежде чем использовать dill вместо pickle , имейте в виду, что dill не включен в стандартную библиотеку интерпретатора Python и обычно работает медленнее, чем pickle .
Несмотря на то, что он dill позволяет сериализовать более широкий диапазон объектов pickle , он не может решить все проблемы с сериализацией, которые могут у вас возникнуть. Если вам, например, необходимо сериализовать объект, который содержит соединение с базой данных, то у вас непростое время, потому что этот объект даже не для сериализации dill .
Итак, как вы можете решить эту проблему?
Решением в этом случае является исключение объекта из процесса сериализации и повторная инициализация соединения после десериализации объекта.
Вы можете использовать, __getstate__() чтобы определить, что должно быть включено в процесс травления. Этот метод позволяет вам указать, что вы хотите pickle. Если вы не переопределите __getstate__() , __dict__ то будут использованы экземпляры по умолчанию .
В следующем примере вы увидите, как вы можете определить класс с несколькими атрибутами и исключить один атрибут из сериализации с помощью __getstate()__ :
В этом примере вы создаете объект с тремя атрибутами. Поскольку один из атрибутов – это lambda объект, его нельзя unpicklable стандартным pickle модулем.
Чтобы решить эту проблему, вы должны указать, что pickle __getstate__() . Сначала вы клонируете весь __dict__ экземпляр, чтобы все атрибуты были определены в классе, а затем вручную удаляете c атрибут unpicklable .
Если вы запустите этот пример и затем десериализуете объект, то увидите, что новый экземпляр не содержит c атрибут:
Но что, если вы захотите выполнить некоторые дополнительные инициализации при снятии травления, скажем, добавив исключенный c объект обратно в десериализованный экземпляр? Вы можете сделать это с помощью __setstate__() :
Передав исключенный c объект в __setstate__() , вы гарантируете, что он появится в __dict__ строке без выделения.
Сжатие Pickled объектов
Хотя pickle формат данных является компактным двоичным представлением структуры объекта, вы все равно можете оптимизировать свою засеченную строку, сжимая ее с помощью bzip2 или gzip .
Чтобы сжать Pickled строку bzip2 , вы можете использовать bz2 модуль из стандартной библиотеки.
В следующем примере вы возьмете строку, выделите ее, а затем сожмете ее с помощью bz2 библиотеки:>>>
При использовании сжатия помните, что файлы меньшего размера создаются за счет более медленного процесса.
Проблемы безопасности с pickle модулем Python
Теперь вы знаете, как использовать pickle модуль для сериализации и десериализации объектов в Python. Процесс сериализации очень удобен, когда вам нужно сохранить состояние вашего объекта на диск или передать его по сети.
Однако есть еще одна вещь, которую вам нужно знать о pickle модуле Python : он небезопасен. Вы помните обсуждение __setstate__() ? Что ж, этот метод отлично подходит для выполнения большей инициализации во время удаления, но он также может быть использован для выполнения произвольного кода в процессе удаления!
Итак, что вы можете сделать, чтобы уменьшить этот риск?
К сожалению, не так уж много. Правило – никогда не распаковывать данные, которые поступают из ненадежного источника или передаются по небезопасной сети . Чтобы предотвратить man-in-the-middle attacks , рекомендуется использовать библиотеку hmac чтобы подписывать данные и следить за тем, чтобы они не были подделаны.
В следующем примере показано, как открепление несанкционированного доступа может раскрыть вашу систему злоумышленникам, даже предоставив им работающую удаленную оболочку:
В этом примере выполняется процесс расщепления __setstate__() , который выполняет команду Bash, чтобы открыть удаленную оболочку для 192.168.1.10 компьютера через порт 8080 .
Вот как вы можете безопасно протестировать этот скрипт на вашем Mac или Linux. Сначала откройте терминал и используйте nc команду для прослушивания соединения с портом 8080:
Это будет терминал атакующего . Если все работает, то команда будет висеть.
Затем откройте другой терминал на том же компьютере (или на любом другом компьютере в сети) и выполните приведенный выше код Python для удаления вредоносного кода. Обязательно измените IP-адрес в коде на IP-адрес вашего атакующего терминала. В моем примере IP-адрес злоумышленника 192.168.1.10 .
Выполнив этот код, жертва предоставит атакующему оболочку:
Если все работает, на атакующей консоли появится оболочка Bash. Эта консоль теперь может работать непосредственно на атакуемой системе:
Итак, позвольте мне повторить эту критическую точку еще раз: не используйте pickle модуль для десериализации объектов из ненадежных источников!
Вывод
Теперь вы знаете, как использовать pickle модуль Python для преобразования иерархии объектов в поток байтов, который можно сохранить на диск или передать по сети. Вы также знаете, что процесс десериализации в Python должен использоваться с осторожностью, поскольку извлечение чего-либо из ненадежного источника может быть чрезвычайно опасным.
В этом уроке вы узнали:
- Что означает сериализация и десериализация объекта
- Какие модули вы можете использовать для сериализации объектов в Python
- Какие виды объектов можно сериализовать с помощью pickle модуля Python
- Как использовать pickle модуль Python для сериализации объектных иерархий
- Каковы риски unpickling из ненадежного источника
Обладая этими знаниями, вы хорошо подготовлены для сохранения ваших объектов с помощью pickle модуля Python .
Работа с файлами в Питоне представлена широким набором возможностей. Имеются как встроенные инструменты, так и сторонние модули и библиотеки, позволяющие открывать и читать документы, а также записывать в них любую информацию.
Python умеет взаимодействовать со следующими форматами файлов: txt, jpg, csv, json, html, xlsx, pdf и целым рядом других. Удобство заключается в том, что для каждого случая есть отдельный модуль, ускоряющий разработку.
Виртуальная среда под проекты
Язык Python удобен тем, что может взаимодействовать с разными проектами при различных настройках. Как сказал создатель протокола BitTorrent Брэм Коен:
Хорошей практикой считается активация виртуальной среды под конкретную проблему. Другими словами, устанавливать библиотеки нужно не глобально, для всей операционной системы, а для отдельного проекта. В этом помогает виртуальное окружение. Прежде чем переходить к написанию кода, нужно сформировать окружение проекта.
В Windows это делается следующим образом (в нужной папке открываем терминал и прописываем команды):
В UNIX-системах (Linux, MacOS) команды будут такими:
Открытие и чтение текстового файла
Для этого в Питоне имеются следующие конструкции:
- Функция open() – открывает документ в виде файлового объекта;
- Функция close() – закрывает файл и удаляет его из оперативной памяти;
- Контекстный менеджер with (автоматически очищает память после работы с файлом). Его синтаксис показан на рисунке ниже.
- Метод read() – считывает документ полностью или частично в виде строки;
- Метод readline() – построчно выводит содержимое объекта;
- Метод readlines() – формирует из строк файла список.
Писать код будем в IDE PyCharm (среду разработки скачиваем с официального сайта).
Режимы работы с документом
Вторым параметром в функцию open() передается режим работы с файлом. Охарактеризуем их (таблица 1).
Режим | Характеристика |
r | Открыть для чтения |
w | Открыть для записи (если такого документа не существует, то он будет создан) |
a | Дописать новое содержимое в файл в дополнение к имеющемуся |
x | Открыть для записи в несуществующий файл |
t | Представить контент как текст |
+ | Открыть документ как для чтения, так и записи |
b | Представить контент в виде байтов |
Запись текстового контента в файл
Запись текста возможна двумя способами:
- Через функцию write(),
- При помощи функции print().
Чтение и запись json-файлов
Для работы с json-объектами предусмотрен встроенный модуль json. Его нужно импортировать для начала.
Практически все объекты Питона можно безболезненно преобразовывать в json-сущности.
В библиотеке json имеется 4 основные функции (таблица 2).
Функция | Характеристика |
dumps() | Преобразовывает объекты Питона в json |
dump() | Записывает преобразованные в json-формат данные в файл |
loads() | Преобразовывает json-данные в словарь |
load() | Считывает содержимое json-файла и делает из них словарь |
Так как мы рассматриваем тему создания и чтения файлов, то будем использовать соответствующие инструменты.
Теперь считаем их и представим в виде словаря Python.
Как видно, десериализация json-данных осуществляется следующим образом:
- Двойные кавычки преобразованы в одинарные;
- Булево значение false превратилось в False;
- Объект null соответствует значению None в Питоне.
Запись excel-файлов
Для сохранения табличных данных удобнее всего пользоваться библиотекой csv, так как с этим форматом работать проще, он быстрее, может открываться без наличия Excel на рабочем компьютере.
Основные инструменты, с которыми будем работать:
- Workbook() – класс для создания табличного файла;
- Create_sheet() – внедрение страницы с определенным именем;
- Save() – сохранение результата в файл;
- Cell() – запись информации в ячейку;
- Get_column_letter() – получение буквенного обозначения колонки.
В результате в созданном файле будем иметь следующее содержимое (рисунок 2).
Рисунок 2 – Результат наполнения xlsx-файла
Файлы операционной системы
Встроенный модуль os позволяет просматривать содержимое каталогов и редактировать его.
Ознакомимся со следующими функциями:
- mkdir() – создание папки в выбранном каталоге;
- walk() – определение списка всех файлов и директорий внутри заданной и ее подпапках;
- remove() – удаление файла из системы;
- rename() – переименование документа и пр.
Приведем несколько примеров работы с библиотекой.
Редактирование изображений в Питоне
Для работы с картинками используют внешний модуль Pillow. Он позволяет создавать и изменять рисунки, а также накладывать на них текст.
В первую очередь следует установить модуль:
Нарисуем квадрат красного цвета с длиной стороны 400 пикселей, применим к нему фильтр размытия, а затем сделаем его черно-белым.
Рисунок 3 – Красный квадрат Рисунок 4 – Размытие картинки Рисунок 5 – Преобразование в черно-белый цвет
Заключение
Мы рассмотрели лишь часть возможностей Питона по работе с файлами. Создание, считывание, вывод в файлы может осуществляться разными способами. Более того, практически все форматы и типы документов могут редактироваться при помощи Python. В зависимости от задачи найти нужный модуль не составит труда.
Ответы на вопросы читателей
При постоянной практике и достаточном ежедневном внимании к языку Python основам синтаксиса и базовым операциям можно научиться за 1-2 месяца. Уверенное владение базовыми библиотеками, популярными сторонними модулями, объектно-ориентированном подходе может потребовать от 3 до 6 месяцев. Нужно осознавать и то, что для каждого обучаемого сроки индивидуальны.
Взаимодействие с текстовыми файлами связано с функциями open(), close(), read(), readlines(), контекстным менеджером with и рядом других. Эти инструменты позволяют как читать документы, так и осуществлять в них запись.
Универсальный формат табличной информации – csv (Comma Separated Values, разделенные запятой данные). Его хорошо понимают разные сайты, среды разработки, операционные системы.
Чтобы взаимодействовать с excel-файлами требуется установить модуль openpyxl.
Для работы с Гугл-таблицами нужно получить доступ к программному интерфейсу в качестве разработчика.
Информация на Интернет-ресурсах зачастую представлена в виде json-данных. Она очень напоминает словари (dictionaries) в Питоне. Именно поэтому работать с этим форматом очень удобно.
Он используется для передачи и получения информации между API сайтов и программ.
После создания файлового объекта его можно прочитать полностью и вывести на печать.
В зависимости от исходных данных pdf-документы могут создаваться при помощи разных инструментов: Pillow (когда входная информация в основной своей массе графическая), PyPDF2 (объединение файлов, кодирование-декодирование), fpdf (преобразование текста в pdf-формат) и пр.
Один из самых часто применяемых инструментов – библиотека Pillow. Позволяет решать задачи: извлекать сведения о картинке; менять размеры, обрезать, поворачивать; накладывать фильтры на рисунки (размытие, повышение контраста и др.); добавлять текстовые надписи; создавать изображения.
Pickle в Python используется для сериализации и десериализации структуры объекта. Любой объект можно законсервировать, чтобы потом сохранить на диске.
Сначала pickle сериализует объект, а затем преобразует объект в символьный поток, чтобы он содержал всю информацию, необходимую для восстановления объекта в другом скрипте.
Обратите внимание, что модуль pickle не защищен от ошибочных или злонамеренно созданных данных в соответствии с документацией. Поэтому никогда не отбирайте данные, полученные из ненадежных или не аутентифицированных источников.
pickle.dump()
В этом разделе мы узнаем, как хранить данные с помощью Python pickle. Для этого мы должны сначала импортировать модуль pickle.
Следующая программа предложит вам ввести некоторые данные. В моем случае это было так.
pickle.load()
Чтобы получить данные, шаги довольно просты. Для этого вам нужно использовать функцию pickle.load(). Основным аргументом функции загрузки pickle является объект файла, который вы получаете, открывая файл в режиме двоичного чтения (rb).
Давайте напишем код для получения данных, которые мы обработали, используя код дампа pickle.
Результат будет следующим:
Пример
Я сделал короткое видео, показывающее выполнение примеров программы pickle – сначала для сохранения данных в файл, а затем для их загрузки и печати.
Как вы можете видеть, файл, созданный через pickle dump, является двоичным файлом и показывает символы мусора в текстовом редакторе.
Читайте также: