首页 > 其他分享 >【5.0】常用模块之json、pickle模块

【5.0】常用模块之json、pickle模块

时间:2023-11-25 21:23:30浏览次数:23  
标签:5.0 str python json tm 模块 序列化 pickle

【一】序列化和反序列化

【1】什么是序列化

  • 将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化

【2】为什么要有序列化

  • 比如,我们在 python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?
    • 现在我们能想到的方法就是存在文件里
    • 然后另一个 python 程序再从文件里读出来。
  • 但是我们都知道
    • 对于文件来说是没有字典这个概念的
    • 所以我们只能将数据转换成字典放到文件中。
  • 你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了
    • 为什么我们还要学习序列化模块呢?
  • 没错序列化的过程就是从dic 变成str(dic)的过程。
  • 现在你可以通过str(dic)
    • 将一个名为dic的字典转换成一个字符串,
  • 但是你要怎么把一个字符串转换成字典呢?
    • 聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。
    • eval()函数十分强大,但是eval是做什么的?
      • 官方demo解释为:
      • 将字符串str当成有效的表达式来求值并返回计算结果。
      • BUT!强大的函数有代价。安全性是其最大的缺点。
  • 想象一下
    • 如果我们从文件中读出的不是一个数据结构,
    • 而是一句"删除文件"类似的破坏性语句
    • 那么后果实在不堪设设想。
      而使用eval就要担这个风险。
  • 所以
    • 我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)

【3】序列化的目的

  • 以某种存储形式使自定义对象持久化
  • 将对象从一个地方传递到另一个地方。
  • 使程序更具维护性。

img

【二】序列化模块json

【1】导入模块

import json

【2】序列化方法(loads)

  • 将json字符串转换为Python对象
import json

json_str = '{"name": "Dream", "age": 30, "city": "Shang Hai"}'
python_obj = json.loads(json_str)

print(python_obj,type(python_obj))
# {'name': 'Dream', 'age': 30, 'city': 'Shang Hai'} <class 'dict'>
# 注释:将 JSON 字符串解码为 Python 字典

【2】反序列化(dumps)

  • 将Python对象转换为json字符串
  • json转换完的字符串类型的字典中的字符串是由 "" 表示的
import json

python_obj = {"name": "Dream", "age": 30, "city": "Shang Hai"}
json_str = json.dumps(python_obj, indent=2)
print(json_str, type(json_str))
# {
#   "name": "Dream",
#   "age": 30,
#   "city": "Shang Hai"
# } <class 'str'>

# 注释:将 Python 字典编码为漂亮格式的 JSON 字符串

【3】写入文件(dump)

(1)不指定参数

  • 接收一个文件句柄
  • 直接将字典 转换成 json字符串 写入文件
import json

python_obj = {"name": "John", "age": 30, "city": "New York"}
with open("data.json", "w") as json_file:
    # indent : 控制缩进的空格数或字符串
    json.dump(python_obj, json_file, indent=2)

# 注释:将 Python 字典写入 JSON 文件
  • 会在本地生成一个 data.json 的文件在里面有上面写入的数据

(2)指定参数编码(ensure_ascii)

import json

python_obj = {"name": "蚩梦", "age": 30, "city": "Shang Hai"}
# 写文件时指定编码格式为 utf-8 ---> 这样在json文件中存储的中文才是正常的中文,否则是二进制数据
with open("data.json", "w",encoding='utf-8') as json_file:
    #  ensure_ascii=False 上面指定编码格式后需要将 默认使用 ascii 这个选项设置为否
    json.dump(python_obj, json_file, indent=2,ensure_ascii=False)

# 注释:将 Python 字典写入 JSON 文件
# 未指定 encoding='utf-8'
{
  "name": "\u86a9\u68a6",
  "age": 30,
  "city": "Shang Hai"
}

# 指定 encoding='utf-8'
{
  "name": "蚩梦",
  "age": 30,
  "city": "Shang Hai"
}

(3)指定参数分隔符(separators)

import json

python_obj = {"name": "蚩梦", "age": 30, "city": "Shang Hai"}
with open("data.json", "w", encoding='utf-8') as json_file:
    
    # 将默认的分隔符 , 替换成我们的指定分隔符 -
    # 将默认的分隔符 : 替换成我们的指定分隔符 ; 
    json.dump(python_obj, json_file, indent=2, ensure_ascii=False, separators=(',', ';'))

# 注释:将 Python 字典写入 JSON 文件
{
  "name";"蚩梦"-
  "age";30-
  "city";"Shang Hai"
}

(4)其他参数

Serialize obj to a JSON formatted str.(字符串表示的json对象) 

Skipkeys:
	默认值是False
    	如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None)设置为False时,就会报TypeError的错误。
    	此时设置成True,则会跳过这类key 

ensure_ascii:
    当它为True的时候
    	所有非ASCII码字符显示为\uXXXX序列
        只需在dump时将ensure_ascii设置为False即可
        此时存入json的中文即可正常显示。

If check_circular is false, then the circular reference check for container types will be skipped and a circular reference will result in an OverflowError (or worse). 
If allow_nan is false, then it will be a ValueError to serialize out of range float values (nan, inf, -inf) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (NaN, Infinity, -Infinity). 

indent:
	应该是一个非负的整型
    	如果是0就是顶格分行显示
        如果为空就是一行最紧凑显示
        否则会换行且按照indent的数值显示前面的空白分行显示
    这样打印出来的json数据也叫pretty-printed json 

separators:
	分隔符
    	实际上是(item_separator, dict_separator)的一个元组
        默认的就是(‘,’,’:’);
        	这表示dictionary内keys之间用“,”隔开
            而KEY和value之间用“:”隔开。 

            
default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. 

sort_keys:
	将数据根据keys的值进行排序。 

To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.

【4】读文件数据(load)

  • 接收一个文件句柄
  • 直接将文件中的 json字符串 转换成 数据结构返回
import json

# 可以选择指定读取数据的默认编码格式
with open("data.json", "r",encoding='utf-8') as json_file:
    python_obj = json.load(json_file)
    print(python_obj, type(python_obj))
    # {'name': '蚩梦', 'age': 30, 'city': 'Shang Hai'} <class 'dict'>

# 注释:从 JSON 文件中读取数据并转为 Python 字典
  • 会从 data.json 中将数据读出来并转换为Python字典

【三】序列化模块pickle

  • json & pickle 模块 (用于序列化的两个模块)

  • json

    • 用于字符串 和 python数据类型间进行转换
  • pickle

    • 用于python特有的类型 和 python的数据类型间进行转换

【1】序列化方法(dumps)

import pickle

dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)
# b'\x80\x04\x95#\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x02k1\x94\x8c\x02v1\x94\x8c\x02k2\x94\x8c\x02v2\x94\x8c\x02k3\x94\x8c\x02v3\x94u.'
print(type(str_dic))
# <class 'bytes'>

【2】反序列化方法(loads)

import pickle

dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)
# b'\x80\x04\x95#\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x02k1\x94\x8c\x02v1\x94\x8c\x02k2\x94\x8c\x02v2\x94\x8c\x02k3\x94\x8c\x02v3\x94u.'
print(type(str_dic))
# <class 'bytes'>

dic2 = pickle.loads(str_dic)
print(dic2) 
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
print(type(dic2))
# <class 'dict'>

【3】写入文件(dump)

import pickle
import time

struct_time = time.localtime()
print(struct_time)
# time.struct_time(tm_year=2023, tm_mon=11, tm_mday=25, tm_hour=20, tm_min=9, tm_sec=46, tm_wday=5, tm_yday=329, tm_isdst=0)

# 打开文件,并将句柄给 f
f = open('pickle_file', 'wb')
# 向 pickle_file 文件中写入数据
pickle.dump(struct_time, f)
# 完成写入,关闭文件
f.close()
  • 写入到 pickle_file 文件里面的数据是一堆乱码,看不懂
€昫       ?time攲struct_time敁?M?K	K	K	K.K(KK麷 t攠??tm_zone攲涓浗鏍囧噯鏃堕棿攲	tm_gmtoff擬€pu啍R?

【4】读文件数据(load)

import pickle

# 打开文件的句柄
f = open('pickle_file', 'rb')
# 将读出来的数据给 struct_time2
struct_time2 = pickle.load(f)

# 我们可以直接操作 struct_time2 --- 上面直接写入的时间元组对象
print(struct_time2)
# time.struct_time(tm_year=2023, tm_mon=11, tm_mday=25, tm_hour=20, tm_min=9, tm_sec=46, tm_wday=5, tm_yday=329, tm_isdst=0)

print(type(struct_time2))
# <class 'time.struct_time'>
print(struct_time2.tm_year)
# 2023

【5】小练习

  • 将Python特有的函数写入文件
import pickle

def index():
    print(f" 这是index 函数")
    
# 将函数对象写入文件
with open('my_func', 'wb') as f:
    print(index)
    # <function index at 0x0000024D28D03E20>
    pickle.dump(index, f)
  • 将Python特有的函数对象在文件中读出来并调用
import pickle


def index():
    print(f" 这是index 函数")


# 将函数对象写入文件
with open('my_func', 'rb') as f:
    data = pickle.load(f)
    print(data)
    # <function index at 0x0000027D9C893E20>
    data()
    # 这是index 函数

【四】小结

  • 这时候机智的你又要说了,既然pickle如此强大,为什么还要学json呢?
  • 这里我们要说明一下
    • json是一种所有的语言都可以识别的数据结构。
  • 如果我们将一个字典或者序列化成了一个json存在文件里
    • 那么java代码或者js代码也可以拿来用。
  • 但是如果我们用pickle进行序列化
    • 其他语言就不能读懂这是什么了~
  • 所以,如果你序列化的内容是列表或者字典,我们非常推荐你使用json模块
  • 如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用python对这个数据进行反序列化的话,那么就可以使用pickle

标签:5.0,str,python,json,tm,模块,序列化,pickle
From: https://www.cnblogs.com/dream-ze/p/17856105.html

相关文章

  • 课程模块
    06-01课程主页面之前台FreeCourse.vue<template><divclass="course"><Header></Header><divclass="main"><!--筛选条件--><divclass="condition">......
  • 【9.0】Python高级之常用模块学习
    【一】re【二】time、datetime【三】os......
  • 【2.0】常用模块之time、datetime模块
    【一】时间模块(time/datetime)【二】表示时间的三种方式在Python中,通常有这三种方式来表示时间:时间戳元组(struct_time)格式化的时间字符串:格式化的时间字符串(FormatString):‘1999-12-06’【三】time(1)导入时间模块importtime(2)时间戳(time)[1]生成时间戳......
  • 【1.0】常用模块之re模块
    【一】正则语法【1】引入一说规则我已经知道你很晕了现在就让我们先来看一些实际的应用。在线测试工具http://tool.chinaz.com/regex/首先你要知道的是谈到正则,就只和字符串相关了。在我给你提供的工具中,你输入的每一个字都是一个字符串。其次,如果在一个位置的一......
  • 【3.0】常用模块之os模块
    【一】文件操作(os)__file__是指当前文件【二】文件路径相关(path)(1)获取当前文件路径(abspath)importos#获取当前文件路径file_path=os.path.abspath(__file__)print(file_path)#E:\PythonProjects\07常用模块学习\03os模块.py(2)获取当前文件所在文件夹路径(dirn......
  • 聚合工程的微服务之创建父工程和子模块
    1、创建父工程创建一个普通的Maven项目,File》New》Project》MavenArchetype父级的pom文件只作项目子模块的整合,在maveninstall时不会生成jar/war压缩包。创建好后删除刚创建工程里不需要的文件,只保留:.idea 文件夹、项目 pom 文件,如果没有.gitignore文件,就在根目录下......
  • Python文件锁portalocker模块
    在多进程/多线程的学习后,终于来到了“文件锁”这个概念阶段,文件锁的存在就是由于在多进程/线程操作时会对某个文件进行频繁修改,而导致读取与修改的数据产生不同步。典型场景有以下:进程1对文件A进行写入操作,写入一条记录a,持续时间时20s才能完成这个文件的写入。此时进程2在第......
  • 【Django基础】auth认证模块
    https://www.cnblogs.com/DuoDuosg/p/17005583.html一、django的auth认证模块1.什么是auth模块Auth模块是Django自带的用户认证模块:我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,......
  • mysql5.0升级8.0完成后,服务器重启引发"#1449 - The user specified as a definer ('m
    遇到的问题:问题一:ERROR1449(HY000):Theuserspecifiedasadefiner('mysql.infoschema'@'localhost')doesnotexist异常原因:未知解决办法:验证指定的用户('mysql.infoschema'@'localhost')是否存在于mysql数据库中SELECTUserFROMmysql.userWH......
  • 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicK
    报错内容 解决办法:在Web.config的<configuration></configuration>中添加如下代码即可。<configuration><runtime><assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assembly......