Python 常用模块

本文介绍了Python中的常用模块,包括序列化模块(json、pickle、shelve)的应用,hashlib模块的密码加密与文件一致性校验,collections模块中的namedtuple、deque、Counter、OrderedDict和defaultdict,以及os和sys模块的功能。详细探讨了序列化的意义、用途及各种模块的使用场景,帮助读者更好地理解和运用Python的内置模块。
摘要由CSDN通过智能技术生成

一、什么是模块

常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。

但其实import加载的模块分为四个通用类别:

1 使用python编写的代码(.py文件)

2 已被编译为共享库或DLL的C或C++扩展

3 包好一组模块的包

4 使用C编写并链接到python解释器的内置模块

为何要使用模块?

如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。

随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用。

二、序列化模块

什么叫序列化——将原本的字典、列表等内容转换成一个字符串或者bytes的过程就叫做序列化

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

为什么要有序列化模块?

数据结构转化成这个特殊的序列有什么用呢? 这个才是序列化的关键所在,这个特殊的序列大有用处。举例说明:

比如,你的程序中需要一个字典类型的数据存放你的个人信息:

dic = {
   'username':'山药', 'password': 123456,'login_status': True}

你的程序中有一些地方都需要使用这个dic数据,登录时会用到,注册时也会用到。那么我们之前就是将这个dic写在全局里,但是这样是不合理的,应该是将这数据写入一个地方存储(还没有学数据库),现在先存放在一个文件中,那么程序中哪里需要这个数据了,你就读取文件取出你需要的信息即可。那么有没有什么问题? 你将这个字典直接写入文件是不可以的,必须转化成字符串的形式,而且你读取出来也是字符串形式的字典。

那么你拿到一个str(dic)有什么用?他是根本转化不成str的(不能用eval很危险),所以很不方便。那么这时候序列化模块就起到作用了,如果你写入文件中的字符串是一个序列化后的特殊的字符串,那么当你从文件中读取出来,是可以转化回原数据结构的。这个就很牛逼了。

下面说的是json序列化,pickle序列化有所不同:

json序列化除了可以解决写入文件的问题,还可以解决网络传输的问题,比如你将一个list数据结构通过网络传给另个开发者,那么你不可以直接传输,之前我们说过,你要想传输出去必须用bytes类型。但是bytes类型只能与字符串类型互相转化,它不能与其他数据结构直接转化,所以,你只能将list —> 字符串 —> bytes 然后发送,对方收到之后,在decode() 解码成原字符串。此时这个字符串不能是我们之前学过的str那种字符串,因为它不能反解,必须要是这个特殊的字符串,他可以反解成list ,这样开发者之间就可以借助网络互传数据了,不仅仅是开发者之间,你要借助网络爬取数据这些数据多半是这种特殊的字符串,你接受到之后,在反解成你需要的数据类型。

对于这个序列化模块我们做一个小小总结:

序列化模块就是将一个常见的数据结构转化成一个特殊的序列,并且这个特殊的序列还可以反解回去。它的主要用途:文件读写数据,网络传输数据

Python中这种序列化模块有三种:

  • json模块 : (重点

    • 不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符串。(比如Python的一个列表[1, 2, 3]利用json转化成特殊的字符串,然后在编码成bytes发送给php的开发者,php的开发者就可以解码成特殊的字符串,然后在反解成原数组(列表): [1, 2, 3])
    • json序列化只支持部分Python数据结构:dict,list, tuple,str,int, float,True,False,None
  • pickle模块:

    • 只能是Python语言遵循的一种数据转化格式,只能在python语言中使用。
    • 支持Python所有的数据类型包括实例化对象。
  • shelve模块:类似于字典的操作方式去操作特殊的字符串

序列化的目的

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aRgtuC69-1598951530859)(…/…/Typora/Image/image-20200830141634043.png)]

Python可序列化的数据类型

| Python         |     JSON       |

| dict           |     object     |

| list, tuple    |     array      |

| str            |     string     |

| int, float     |     number      |

| True           |     true      |

| False          |     false     |
 
| None           |     null     |

2.1 json模块

Json模块提供了四个功能:dumps、dump、loads、load

用于网络传输:dumps、loads

import json
dic = {
   'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) # 序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic)
'''
<class 'str'> {"k1": "v1", "k2": "v2", "k3": "v3"}
# 注意,json转换完的字符串类型的字典中的字符串是由""表示的
'''
dic2 = json.loads(str_dic) # 反序列化:将一个字符串格式的字典转换成一个字典
print(type(dic2),dic2)
'''
<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
'''

list_dic = [1,['a','e','f'],3,{
   'k1':'v1','k2':'v2','k3':'v3'}]
str_dic2 = json.dumps(list_dic) #也可以处理嵌套的数据类型
print(type(str_dic2),str_dic2)
'''
<class 'str'> [1, ["a", "e", "f"], 3, {"k1": "v1", "k2": "v2", "k3": "v3"}]
'''
list_dic2 = json.loads(str_dic2)
print(type(list_dic2),list_dic2)
'''
<class 'list'> [1, ['a', 'e', 'f'], 3, {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}]
'''

用于文件写读:dump、load

import json
f = open('json_file',mode='w',encoding='utf-8')
dic = {
   'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)  # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()

f = open('json_file')
dic2 = json.load(f) # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)

其他参数说明

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的中文即可正常显示。)
  • indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,这样打印出来的json数据也叫pretty-printed json
  • separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。
  • sort_keys:将数据根据keys的值进行排序。
import json
data = {
   'username':['尼古拉斯赵4','杨把总'],'sex':'male','age':'18'}
json_dic = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False)
print(json_dic)
'''
{
  "age":"18",
  "sex":"male",
  "username":[
    "尼古拉斯赵4",
    "杨把总"
  ]
}
'''

json序列化存储多个数据到同一个文件中

对于json序列化,存储多个数据到一个文件中是有问题的,默认一个json文件只能存储一个json数据,但是也可以解决,举例说明:

import json
dic1 = {
   'name':'lisi'}
dic2 = {
   'subject':'Python'}
dic3 = {
   'age':'18'}
f = open('mul_json',mode='a',encoding='utf-8')
json.dump(dic1,f)
json.dump(dic2,f)
json.dump(dic3,f)
f.close()

f = open('mul_json',encoding='utf-8')
json_dic = json.load(f)
json_dic2 = json.load(f)
json_dic3 = json.load(f)
print(type(f),json_dic)

上面会报错

解决办法:

import json
dic1 = {
   'name':'lisi'}
dic2 = {
   'subject':'Python'}
dic3 = {
   'age':'18'}
f = open('mul_json',mode='a',encoding='utf-8')
str1 = json.dumps(dic1)
f.write(str1+'\n')
str2 = json.dumps(dic2)
f.write(str2+'\n')
str3 = json.dumps(dic3)
f.write(str3+'\n')
f.close()

f = open('mul_json',encoding='utf-8')
for line in f:
    print(json.loads(line))
'''
{'name': 'lisi'}
{'subject': 'Python'}
{'age': '18'}
'''

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值