首页 > 其他分享 >Pickle模块

Pickle模块

时间:2023-12-12 14:48:40浏览次数:28  
标签:序列化 字节 Pickle dic data 模块 x00 pickle

序列化:把对象转化成二进制字节
反序列化:把二进制字节转化回对象

Pickle模块的常见用法:

Pickle.dunps   把对象(数据)转化成字节
Pickle.loads   把字节转化回对象(数据)
Pickle.dunp   把对象序列化成字节之后写入到文件
Pickle.load   把文件中的字节反序列化成对象

在Python中,序列化和反序列化是将数据结构转换为字节流或其他可存储或传输的格式,以及将字节流或其他格式还原为原始数据结构的过程。

序列化(Serialization)

序列化通常涉及将数据结构转换为字节流或字符串的过程,以便将其保存到文件、数据库或通过网络传输。

使用pickle模块的pickle.dumps()方法进行序列化。

反序列化(Deserialization)

反序列化是将字节流或其他格式还原为原始数据结构的过程。

使用 pickle 模块的 pickle.loads() 方法进行反序列化。

 

案例1:文件存储

pickle.dumps() 用于将字典 data 序列化为字节流,并将其写入文件 'data.pkl'

import pickle

data = {'name': 'John', 'age': 30, 'city': 'New York'}

# 序列化
serialized_data = pickle.dumps(data)
with open('data.pkl', 'wb') as file:
    file.write(serialized_data)

pickle.loads() 用于将字节流反序列化为原始的数据结构。

import pickle

# 从文件中读取序列化的数据
with open('data.pkl', 'rb') as file:
    serialized_data = file.read()

# 反序列化
loaded_data = pickle.loads(serialized_data)
print(loaded_data)

案例2:网络传输

pickle.dumps()将列表序列化为字节流,才可以进行网络传输(因为网络底层只认识字节)

import pickle

lst = ["成龙", "赵本山", "范伟"]
bs = pickle.dumps(lst)
print(bs)

#运行结果
b'\x80\x04\x95#\x00\x00\x00\x00\x00\x00\x00]\x94(\x8c\x06\xe6\x88\x90\xe9\xbe\x99\x94\x8c\t\xe8\xb5\xb5\xe6\x9c\xac\xe5\xb1\xb1\x94\x8c\x06\xe8\x8c\x83\xe4\xbc\x9f\x94e.'

pickle.loads()将网络传输过来的字节,重新还原回原始的数据结构。

bs = b'\x80\x04\x95#\x00\x00\x00\x00\x00\x00\x00]\x94(\x8c\x06\xe6\x88\x90\xe9\xbe\x99\x94\x8c\t\xe8\xb5\xb5\xe6\x9c\xac\xe5\xb1\xb1\x94\x8c\x06\xe8\x8c\x83\xe4\xbc\x9f\x94e.'
lst = pickle.loads(bs)
print(lst)

#运行结果
['成龙', '赵本山', '范伟']

需要注意的是,pickle 不是唯一的序列化方法。在实际应用中,你可能还会遇到其他格式,比如 JSON(使用 json 模块)、XML、或者 Protocol Buffers 等,取决于你的需求和使用场景。

反面案例

dic = {"name": "admin", "password": 123}
f = open("data.txt", mode="w", encoding="utf-8")
f.write(dic)

#运行结果
    f.write(dic)
TypeError: write() argument must be str, not dict    #write() 方法中传递的参数必须是字符串(str),而不能是字典(dict)

如果你强制转化成字符串去存储这个字典,str(dic)虽然执行会成功

dic = {"name": "admin", "password": 123}
f = open("data.txt", mode="w", encoding="utf-8")
f.write(str(dic))

但是当你重新读取f.read()文件的时候,读取出来的结果依旧是字符串(str),而不是字典(dict)

f = open("data.txt", mode="r", encoding="utf-8")
s = f.read()
print(s, type(s))

#运行结果,依旧是字符串类型
{'name': 'admin', 'password': 123} <class 'str'>

这样,你就不能像字典一样进行关键字取值、循环等操作。

 

为了解决这个问题,你还得使用eval()进行特殊处理

f = open("data.txt", mode="r", encoding="utf-8")
s = f.read()

d = eval(s)
print(d, type(d))

#运行结果
{'name': 'admin', 'password': 123} <class 'dict'>

但是,使用 eval() 函数来解析字符串是一个潜在的安全风险,因为它可以执行任意的 Python 代码,可能导致代码注入或执行恶意代码的风险。强烈建议避免使用 eval() 来解析未知或不可信来源的数据。

在你的情况下,如果你知道文件中包含的是一个合法的字典表示形式,更安全的方法是使用 json 模块来加载 JSON 数据:

import json

with open("data.txt", mode="r", encoding="utf-8") as f:
    json_str = f.read()

loaded_dict = json.loads(json_str)
print(loaded_dict, type(loaded_dict))

这样,你可以确保加载的数据是一个有效的 JSON 格式,而且不会执行任意的代码。

如果你依然需要处理 Python 字典表示形式而非 JSON,可以使用 ast.literal_eval() 而非 eval(),因为 literal_eval() 更安全,只会解析字面常量,而不会执行任意代码。不过,使用 JSON 通常是更好的选择。

 

 

把数据存储到文件中最合理的方案就是使用pickle

dic = {"name": "admin", "password": 123}
pickle.dump(dic, open("data.txt", mode="wb"))

读取序列化的文件

dic = pickle.load(open("data.txt", mode="rb"))
print(dic, type(dic))

#执行结果
{'name': 'admin', 'password': 123} <class 'dict'>

 

标签:序列化,字节,Pickle,dic,data,模块,x00,pickle
From: https://www.cnblogs.com/Magiclala/p/17896749.html

相关文章

  • 多种DC电源模块的比较和评价
    多种DC电源模块的比较和评价BOSHIDADC电源模块是一种重要的电子零件,可以将交流电转换为直流电,并为相应的电路提供所需的电能。随着技术的进步,市场上的DC电源模块种类越来越多,不同类型的DC电源模块有着不同的特点和优缺点。 1.线性稳压模块线性稳压模块是一种简单而实用的DC......
  • Pydantic模块学习
    Pydantic是一个Python库,用于数据验证和设置强类型数据结构。它是一个数据验证库,专门设计用于数据解析和验证,尤其在处理用户输入、API请求等情境中很有用。以下是Pydantic的一些主要特点和用法: 使用Pydantic主要涉及以下几个步骤:定义数据模型:创建一个继承自pydantic......
  • 造纸企业ERP包含哪些模块?造纸企业ERP有什么用
        造纸企业规模的不同,遇到的管理问题各异,有些造纸企业存在多仓库、多平台、多车间数据协同问题,还有些造纸企业内部各个业务环节信息流动速度慢,信息沟通成本较高,不同程度影响企业的车间产能和生产成本等。同期也有不少造纸企业借助ERP系统实现财务整合、随时进行多维属......
  • Livepatch模块的ELF格式要求【ChatGPT】
    https://www.kernel.org/doc/html/v6.6/livepatch/module-elf-format.htmlLivepatch模块的ELF格式要求本文档概述了livepatch模块必须遵循的ELF格式要求。1.背景和动机以前,livepatch需要特定于体系结构的代码来编写重定位。然而,模块加载器中已经存在特定于体系结构的代码来......
  • springboot下添加日志模块和设置日志文件输出
    前言日志的使用将通过SLF4J来使用,SLF4J(SimpleLoggingFacadeforJava)是一个为Java应用提供简单日志记录的接口。它的主要目标是在不同的日志系统之间提供一个简单的抽象层,使得应用能够以一种灵活的方式切换日志实现,而不需要修改应用本身的代码。SLF4J不是一个具体的日志实现,而......
  • _pickle.PicklingError: Can't pickle <class '__main__.aaa'>: attribute lookup aa
    注:其中aaa是我的类名。这个问题是我想保存一个自定义的类对象时,采用如下代码pickle模块保存时出现的报错信息。withopen(f'saved_agent_{seed}.pkl','wb')asfile:pickle.dump(agent,file)出错原因该错误通常出现在试图使用pickle模块保存自定义类对象,而这个类定义......
  • 前端学习笔记202310学习笔记第一百壹拾玖天-模块包-内置模块http之爬虫3
    ......
  • 前端学习笔记202310学习笔记第一百壹拾玖天-模块包-内置模块http之post之3
    varhttp=require("http")varurl=require("url")varhttps=require("https")http.createServer((req,res)=>{varurlobj=url.parse(req.url)res.writeHead(200,{"content-Type":"application/json;......
  • 前端歌谣-第四拾陆课-node之http模块之post
    前言我是歌谣微信公众号关注前端小歌谣一起学习前端知识今天继续给大家讲解node中post请求的讲解案例varhttp=require("http")varurl=require("url")varhttps=require("https")http.createServer((req,res)=>{varurlobj=url.parse(req.url)res.writeHead(200,......
  • 前端学习笔记202310学习笔记第一百壹拾玖天-模块包-内置模块http之post之1
     ......