Python模块

Python模块

序列化模块

序列化后的字符串写入文件,当你从文件中读取出来,是可以转化为原始数据结构的。

python中有三种序列化模块:

  • json模块:

    ​ 不同语言都遵循的一种数据转化格式,即不同语言都使用的特殊字符

    ​ json序列化只支持部分的python数据结构:dict,list,tuple,str,int,float,True,False, None

  • pickle模块:

    ​ 只能是python语言遵循的一种数据转化格式,只能在python语言中使用

    ​ 支持python所有的数据类型,包括实例化对象

  • shelve模块:

    ​ 类似于字典的操作方式去操作特殊的字符串

json模块

json模块是将满足条件的数据结构转化成特殊的字符串,并且也可以反序列化还原回去。

json总共就两对四个方法:

  • 用于网络传输:dumps、loads

  • 用于文件读写:dump、load

json.dumps/json.loads

  1. 可以用于网络传输
# 用于网络传输
# json ------ dumps/loads
import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic)  #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic)  #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
#注意,json转换完的字符串类型的字典中的字符串是由""表示的

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


 #也可以处理嵌套的数据类型 
list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic)
print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
  1. 还可以用于序列化(json)存储多个数据到同一个文件中(dump和load只能存取一个,多个报错)
# 用于序列化
dic1 = {'name':'oldboy1'}
dic2 = {'name':'oldboy2'}
dic3 = {'name':'oldboy3'}
f = open('序列化',encoding='utf-8',mode='a')
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('序列化',encoding='utf-8')
for line in f:
    print(json.loads(line))

json.dump/json.load

# 用于文件传输
# json ------ dump/load
# dump方法接收一个文件句柄,直接将字典转换成json字符串
# load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
# json文件就是专门存储json字符串的文件
import json
f = open('json_file.json','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)
f.close()

f = open('json_file.json')
dic2 = json.load(f)
f.close()
print(type(dic2),dic2)

其他参数:

  • ensure_ascii:默认为True,非ASCII码字符显示为\uXXXX序列,只需在dump时将其设置为False,就可以正常显示中文。

pickle模块

  • pickle模块是将python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去
  • pickle只支持python中的所有数据类型,包括对象

用于网络传输:dumps、loads

用于文件写读:dump、load

pickle.dumps/pickle.loads

# 用于python网络传输
import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)  # bytes类型

dic2 = pickle.loads(str_dic)
print(dic2)    #字典

# 还可以序列化对象
import pickle
def func():
    print(666)

ret = pickle.dumps(func)
print(ret,type(ret)) 

f1 = pickle.loads(ret)
f1()

pickle.dump/pickle.load

# 用于python文件传输
dic = {(1,2):'oldboy',1:True,'set':{1,2,3}}
f = open('pick序列化',mode='wb')
pickle.dump(dic,f)
f.close()
with open('pick序列化',mode='rb') as f1:
    pickle.laod(dic,f1)

其他模块

OS模块

是与操作系统交互的一个接口

  • 当前执行这个python文件的工作目录相关的工作路径
os.getcwd() # 获取当前工作目录,即当前python脚本工作的目录
os.chdir('dirname')  #改变当前脚本工作目录,相当于shell下cd 
  • 和文件夹相关
os.mkdir('dirname')  #生成单级目录
os.rmdir('dirname')  #删除单级空目录,若目录不为空则无法删除,报错
os.makedirs('dirname1/dirname2')  #可生成多层递归目录
os.removedirs('dirname1') #若目录为空则删除,并递归到上一级目录,若为空则删除
os.listdir('dirname)  #列出指定目录下的所有文件和子目录,包括隐藏文件
  • 和文件相关
os.remove()  # 删除一个文件
os.rename('oldname','newname')   #重命名文件
os.stat('path/filename')   # 获取文件、目录信息
# 返回值是一个命名元组,可以通过索引或.访问
  • path系列,和路径相关
os.path.abspath(path)   #返回path规范化的绝对路径
os.path.split(path)   #将path分割成目录和文件名二元组返回
os.path.dirname(path) #返回path的目录。其实就是os.path.split(path)的第一个元素 
os.path.basename(path) #返回path最后的文件名。如何path以/或\结尾,那么就会返回空值,即os.path.split(path)的第二个元素。
os.path.exists(path)  #如果path存在,返回True;如果path不存在,返回False 
os.path.isabs(path)  #如果path是绝对路径,返回True 
os.path.isfile(path)  #如果path是一个存在的文件,返回True。否则返回False  
os.path.isdir(path)  #如果path是一个存在的目录,则返回True。否则返回False 
os.path.join(path1[, path2[, ...]])  #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 
os.path.getatime(path)  #返回path所指向的文件或者目录的最后访问时间  
os.path.getmtime(path)  #返回path所指向的文件或者目录的最后修改时间  
os.path.getsize(path) #返回path的大小

sys模块

重要的就几个

sys.exit(n)      # 退出程序,将整个程序退出
sys.path       # 返回模块的搜索路径(列表格式返回),初始化时使用PYTHONPATH环境变量的值

random模块

主要的几个

随机小数
random.random()    #大于0且小于1之间的小数
random.uniform(1,3)     #大于1,小于3的数


随机整数
random.randint(1,5)   # 大于1小于5之间的整数
random.randrange(1,10,2)    #大于等于1且小于10之间的奇数


随机选择一个返回
random.choice([1,'23',[4,5]])   #1 或者23 或者[4,5]
random.choice([1,'23',[4,5]]2)   # 列表元素任意2个组合

打乱列表顺序
item = [1,3,5,7,9]
random.shuffle(item)  # 打乱次序

例题:生成随机验证码

import random

def v_code():

    code = ''
    for i in range(5):

        num=random.randint(0,9)
        alf=chr(random.randint(65,90))
        add=random.choice([num,alf])
        code="".join([code,str(add)])

    return code

print(v_code())

time模块

  • python 中三种方式来表示时间:时间戳,结构化时间(命名元组),格式化时间
  • 时间戳:时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。返回的是float
  • 结构化时间:返回的是命名元组,可以通过索引和.访问
  • 格式化时间:年月日

时间格式之间的转换

  • 格式化时间 ——-> 时间戳
ft = time.strftime('%Y-%m-%d %H-%M-%S')
st = time.strptime(ft, '%Y-%m-%d %H-%M-%S')  #格式化时间--->结构化时间
t = time.mktime(st)   #结构化时间----->时间戳
  • 时间戳 ———> 格式化时间
t = time.time()
st = time.localtime(t)   # 时间戳----->结构化时间
ft = time.strftime('%Y-%m-%d %H-%M-%S',st)   #结构化时间----->格式化时间

datetime 模块

# datatime模块
import datetime
now_time = datetime.datetime.now()  # 现在的时间
# 只能调整的字段:weeks days hours minutes seconds
print(datetime.datetime.now() + datetime.timedelta(weeks=3)) # 三周后
print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) # 三周前
print(datetime.datetime.now() + datetime.timedelta(days=-3)) # 三天前
print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
print(datetime.datetime.now() + datetime.timedelta(hours=5)) # 5小时后
print(datetime.datetime.now() + datetime.timedelta(hours=-5)) # 5小时前
print(datetime.datetime.now() + datetime.timedelta(minutes=-15)) # 15分钟前
print(datetime.datetime.now() + datetime.timedelta(minutes=15)) # 15分钟后
print(datetime.datetime.now() + datetime.timedelta(seconds=-70)) # 70秒前
print(datetime.datetime.now() + datetime.timedelta(seconds=70)) # 70秒后

current_time = datetime.datetime.now()
# 可直接调整到指定的 年 月 日 时 分 秒 等

print(current_time.replace(year=1977))  # 直接调整到1977年
print(current_time.replace(month=1))  # 直接调整到1月份
print(current_time.replace(year=1989,month=4,day=25))  # 1989-04-25 18:49:05.898601

# 将时间戳转化成时间
print(datetime.date.fromtimestamp(1232132131))  # 2009-01-17

hashlib模块

hashlib的基本使用

hashlib的特征以及使用要点:

  1. bytes类型数据 —> 通过hashlib算法 —> 固定长度的字符串
  2. 不同的bytes类型数据转化成的结果一定不同。
  3. 相同的bytes类型数据转化成的结果一定相同。
  4. 此转化过程不可逆。

主要用途有两个:

  1. 密码的加密
  2. 文件一致性校验

基本代码如下:

import hashlib

s = "Use hashlib!"
md5 = hashlib.md5() # 调用一个md5对象
md5.update(s.encode("utf-8"))  # 调用md5的update()方法,对参数进行加密,加密必须为bytes类型
print(md5.hexdigest())  # 打印加密结果

hashlib的进阶使用——加盐

加盐是个什么玩意呢?加盐就是值比较复杂的加密方式,有点抽象化的词

固定的盐

基本代码如下:

import hashlib

s = "Use hashlib!"
ret = hashlib.md5('abc'.encode('utf-8'))  # abc就是固定的盐
ret.update(s.encode('utf-8'))
print(ret.hexdigest())

动态的盐

基本代码如下:

import hashlib

s = "Use hashlib!"
s1 = '1234567'
ret = hashlib.md5(s1[:2].encode('utf-8'))  # 例如可以修改切片的长度使字符串加的盐每个都不一样
ret.update(s.encode('utf-8'))
print(ret.hexdigest())

hashlib除了md5还提供了其他的加盐方式——sha系列

ret = hashlib.sha1()
ret.update('abc'.encode('utf-8'))
print(ret.hexdigest())

#也可加盐
ret = hashlib.sha384(b'asfdsa')
ret.update('abc'.encode('utf-8'))
print(ret.hexdigest())

# 也可以加动态的盐
ret = hashlib.sha384(b'asfdsa'[::2])
ret.update('abc'.encode('utf-8'))
print(ret.hexdigest())

一般md5就够用了

文件的一致性校验

hashlib模块除了可以用于密码加密之外,还有一个常用的功能,那就是文件的一致性校验。

例:从 Server 端下载文件

Server

# 部分代码
import hashlib
import os
import struct

conn, addr = socket.accept()

file_size = os.path.getsize(file_path)
len_bytes = struct.pack('i', file_size)
conn.send(len_bytes)
with open(file_path, 'rb') as f:
    data_size = 0
    ret = hashlib.md5()
    while data_size < file_size:
        every_data = f.read(1024)
        data_size += len(every_data)
        conn.send(every_data)
        md5.update(data)
    md5_str = md5.hexdigest()
    conn.recv(1024)
    md5_bylen = struct.pack('i', len(md5_str))
    conn.send(md5_bylen)
    conn.send(md5_str)

Client

# 部分代码
import hashlib
import os
import struct

socket = socket.socket()

with open(file_path,mode='wb') as f:
    data_size = 0
    ret = hashlib.md5()
    while data_size < length:
        data = socket.recv(1024)
        f.write(data)
        data_size += len(data)
        md5.update(data)
    md5_str = md5.hexdigest()
    socket.send(b'done')
    md5_bylen = socket.recv(4)
    recvlen_md5 = struct.unpack('i', md5_bylen)[0]
    recv_md5 = socket.recv(recvlen_md5)
    if md5_str == recv_md5:
        print('文件一致')
    else:
        print('文件不一致')

  转载请注明: 浩大大 Python模块

  目录