Python基础知识—pickle/json序列化

2021/11/1 22:09:37

本文主要是介绍Python基础知识—pickle/json序列化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Python基础知识—pickle/json序列化

序列化: 简单理解就是将字典,列表这类的数据,打包保存在电脑硬盘中

  • Pickle
    • pickle.dumps()
    • pickle.dump()
    • pickle.load()
  • Json
    • json.dumps()
    • json.dump()
    • json.load()

1、Pickle

用途:可以用来打包一整个class,但是有风险,有时会失败

  • 将一个字典打包到pickle里,并查看打包之后的样子,pickle.dumps()
import pickle

data = {"filename": "f1.txt", "create_time": "today", "size": 111}
pickle.dumps(data)

b'\x80\x04\x958\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x08filename\x94\x8c\x06f1.txt\x94\x8c\x0bcreate_time\x94\x8c\x05today\x94\x8c\x04size\x94Kou.'

可以看到打包之后的数据已经不能独处它原本的信息了,因为它已经被编码了

所以,如果不需要看懂打包之后数据信息的话,我们就可以使用Pickle来打包,否则可以考虑json

  • pickle.dump()可以将数据直接打包转换成一个文件
import pickle
import os

data = {"filemame": "f1.txt", "create_time": "today", "size": 111}
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

print(os.listdir())

['new_file.txt', 'chinese.txt', 'test.file.py', 'data.pkl']
  • pickle.load(),可以读取上述由pickle.dump()打包生成的文件,并对其进行解析,还原成最初的数据
with open("data.pkl", "rb") as f:
    data = pickle.load()
print(data)

{'filemame': 'f1.txt', 'create_time': 'today', 'size': 111}

除了打包常见的字典,列表,元组这类的数据,pickle甚至都可以打包Python的功能以及类

eg: 定义了一个File类,而且基于它生成了很多file实例,这些实例都是可以被pickle的

注意:在pickle解析时(也可以称作unpickle时),这个File的class一定要有,不然反序列化会因为找不到File类而失败

import pickle


class File:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size

    def change_name(self, new_mame):
        self.name = new_mame


data = File("f2.txt", "now", 222)  # 建立一个File的实例
# 存
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)
# 读
with open("data.pkl", "rb") as f:
    read_data = pickle.load(f)
print(read_data.name)
print(read_data.size)

f2.txt
222

最后unpickle出来的东西还是一个class的实例, 我们可以按照正常的class方式使用它

  • 但有些类型的对象是不能被序列化的,这些通常都是那些需要依赖外部系统状态的对象,比如打开的文件,网络连接,线程,进程,栈帧等。

    如果在class中把上述的东西复制到了class的属性中,会在pickle的时候报错

import pickle


class File:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
        self.file = open(name, "w")


data = File("f3,txt", "now", 222)
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

报错:
TypeError: cannot pickle '_io.TextIOWrapper' object
  • 如果非要使用pickle保存,也是有办法可以解决的。

    用户自定义类可以通过提供__getstate()____setstate__()方法来绕过pickle的这些限制。pickle.dump()会调用__getstate__()获取序列化的对象,__setstate__()__在反序列化时被调用

import pickle


class File:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
        self.file = open(name, "w")

    def __getstate__(self):
        # pickle出去需要能被pickle的信息
        pickled = {"name": self.name, "create_time": self.create_time, "size": self.size}
        return pickled

    def __setstate__(self, pickled_dict):
        # unpickle加载回来,重组class
        self.__init__(
            pickled_dict["name"], pickled_dict["create_time"], pickled_dict["size"]
        )


data = File("f3,txt", "now", 222)
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

with open("data.pkl", "rb") as f:
    read_data = pickle.load(f)
print(read_data.name)
print(read_data.size)

f3,txt
222

2、Json

json数据:Python中的字典、列表都可以是json数据格式

  • 用json读一个python字典
import json

data = {"filename": "f1.txt", "create_time": "today", "size": 111}
j = json.dumps(data)
print(j)
print(type(j))

{"filename": "f1.txt", "create_time": "today", "size": 111}
<class 'str'>

==其实也就是变成了一个字符串形式的字典=

  • 用文件来存储数据,使用json.dump(),和pickle.dump()非常像的方式
import json

data = {"filename": "f1.txt", "create_time": "today", "size": 111}
with open("data.json", "w") as f:
    json.dump(data, f)

print("直接当作纯文本读:")
with open("data.json", "r") as f:
    print(f.read())

print("用json加载了读:")
with open("data.json", "r") as f:
    new_data = json.load(f)

print("字典读取:", new_data["filename"])


直接当作纯文本读:
{"filename": "f1.txt", "create_time": "today", "size": 111}
用json加载了读:
字典读取: f1.txt
  • pickle可以打包python的class,但是json不能序列化保存class,你只可以挑出重要的信息,放在字典或列表中,然后使用json打包字典
class File:
    def __init__(self, name, create_time, size):
        self.name = name
        self.create_time = create_time
        self.size = size
    
    def change_name(self, new_name):
        self.name = new_name

data = File("f4.txt", "now", 222)
# 存,会报错
with open("data.json", "w") as f:
    json.dump(data, f)

3、Pickle和Json的不同

对比PickleJson
存储格式Python特定的Bytes格式通过JSON text格式,可用于常用的网络通讯中
数据种类类,功能,字典,列表,元组等和Pickle一样,但不能存类、功能
保存后可读性不能直接阅读能直接阅读
跨语言性只能用在pyhton可以跨多语言读写
处理时间长(需编码数据)短(不需编码)
安全性不安全相对安全

参考:莫烦Python



这篇关于Python基础知识—pickle/json序列化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程