首页 > Python基础教程 >
-
python基础教程之常用模块介绍
常用模块的介绍:
random
time,datetime
os,sys
hashlib,json,pickle,collections
random模块:
此模块提供了和随机数获取相关的方法:
-
random.random():获取[0.0,1.0)范围内的浮点数
-
random.randint(a,b):获取[a,b]范围内的一个整数
-
random.uniform(a,b):获取[a,b)范围内的浮点数
-
random.shuffle(x):把参数指定的数据中的元素打乱。参数必须是一个可变的数据类型。无返回值
-
random.sample(x,k):从x中随机抽取k个数据,组成一个列表返回。 有返回值
import random # 获取[0.0,1.0)范围内的浮点数 print(random.random()) #0.3255954890152818 # 获取[a,b)范围内的浮点数 print(random.uniform(3,5))#4.683774922271366 # 获取[a,b]范围内的一个整数 print(random.randint(3,10))#4 # random.shuffle(x) 把参数指定的数据中的元素打乱。 lst = list(range(10)) random.shuffle(lst) print(lst)#[8, 3, 0, 9, 5, 1, 4, 6, 2, 7] t = (1,2,3) random.shuffle(t) #报错,参数必须是一个可变的数据类型。 # 通过sample变相实现打乱 t = (1,2,3) lst = random.sample(t,len(t)) print(lst)#[1, 3, 2] ##自: 利用random产生6位数字的验证码 #1 import random s = '' l = random.sample(range(10),6) for i in l: s += str(i) print(s) #如:937640 #2: #获取[a,b]范围内的一个整数 print(random.randint(100000,999999))# 如:337144
time模块:
-
time 模块(和时间相关):封装了获取时间戳和字符串形式的时间的一些方法。
-
三大对象:时间戳, 结构化时间对象(9大字段), 时间字符串【重点】
-
time.time():获取时间戳
-
time.gmtime([seconds]):获取格式化时间对象:是九个字段组成的
-
time.localtime([seconds]):获取格式化时间对象:是九个字段组成的
-
time.mktime(t):时间对象 -> 时间戳
-
time.strftime(format[,t]):把时间对象格式化成字符串
-
time.strptime(str,format):把时间字符串转换成时间对象
-
time模块三大对象之间的转换关系:
-
import time # 获取时间戳 # 时间戳:从时间元年(1970 1 1 00:00:00)到现在经过的秒数。 python:秒数 java:毫秒数 print(time.time())#1558317680.919616 #格林尼治时间 # 获取格式化时间对象:是九个字段组成的。 # 默认参数是当前系统时间的时间戳。默认使用time.time()的返回值。 tm_isdst夏令时 print(time.gmtime())# GMT time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=2, tm_min=1, tm_sec=20, tm_wday=0, tm_yday=140, tm_isdst=0) 模块名.方法名 # 获取时间元年过一秒后,对应的时间对象 print(time.gmtime(1))#time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0) print(time.localtime())#time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=10, tm_min=1, tm_sec=20, tm_wday=0, tm_yday=140, tm_isdst=0) # 时间对象 ---> 时间戳 t1 = time.localtime() #时间对象 t2 = time.mktime(t1) #获取对应的时间戳 print(t2)#1558318103.0 print(time.time())#1558318103.9826832 # 格式化时间对象转换成字符串 strftime(format, p_tuple=None) s = time.strftime("%Y %m %d %H:%M:%S") #注意大小写 print(s,type(s))#2019 05 20 10:05:17 <class 'str'> # 把时间字符串转换成时间对象 strptime(string, format) time_obj = time.strptime('2019 05 20','%Y %m %d') #注意字符串中间加空格'2019 05 20' print(time_obj)#time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=140, tm_isdst=-1) time_obj = time.strptime('2019 05 20 12 30 55','%Y %m %d %H %M %S') print(time_obj)#time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=12, tm_min=30, tm_sec=55, tm_wday=0, tm_yday=140, tm_isdst=-1) #暂停当前程序,睡眠xxx秒 time.sleep(xxx) for i in range(5): print(time.strftime('%Y %m %d %H:%M:%S')) time.sleep(1)
-
datetime模块:
-
datetime模块:日期时间模块,封装了一些和日期、时间相关的类。 类包含若干属性和方法
-
date:需要年,月,日三个参数
-
time:需要时,分,秒三个参数
-
datetime:需要年,月,日,时,分,秒六个参数.
-
timedelta:需要一个时间段.可以是天,秒,微秒.
- timedelta可以和以下三个类进行数学运算: datetime.time, datetime.datetime, datetime.timedelta
-
获取以上类型的对象,主要作用是和时间段进行数学运算. 对时间日期进行数学计算
import datetime #date类 d = datetime.date(2019,5,20) #获取date对象的各个属性 print(d)#2019-05-20 print(d.year)#2019 print(d.month)#5 print(d.day)#20 #time类: t = datetime.time(10,11,55) print(t)#10:11:55 #获取time的各个属性 print(t.hour)#10 print(t.minute)#11 print(t.second)#55 #datetime类: dt = datetime.datetime(2019,5,20,10,11,46) print(dt)#2019-05-20 10:11:46 #timedelta类:时间的变化量 td = datetime.timedelta(days=1) print(td,type(td))#1 day, 0:00:00 <class 'datetime.timedelta'> ##参与数学运算: # 创建时间对象,只能和以下三类进行数学运算: date,datetime,timedelta 【测试】:(date,datetime,timedelta分别于timedelta运算,datetime与date不能运算) td = datetime.timedelta(days=1) d = datetime.date(2010,10,10) res = d - td print(res)#2010-10-09 #timedelta和时间段进行运算的结果类型: 和另一个操作数的类型保持一致 td2 = datetime.date(2010,10,10) td = datetime.timedelta(days=1) res = d + td print(res,type(res))#2010-10-11 <class 'datetime.date'> d = datetime.datetime(2010,10,10,10,10,10) td = datetime.timedelta(days=1) res = d + td print(res,type(res))#2010-10-11 10:10:10 <class 'datetime.datetime'> d = datetime.timedelta(seconds=20) td = datetime.timedelta(days=1) res = d + td print(type(res),res)#<class 'datetime.timedelta'> 1 day, 0:00:20 # 时间变化量的计算会产生进位。 t = datetime.datetime(2010,12,31,23,59,58) td = datetime.timedelta(seconds=3) res = t + td print(res)#2011-01-01 00:00:01 t = datetime.datetime(2010,10,10,10,10,00) td = datetime.timedelta(seconds=3) res = t - td print(res)#2010-10-10 10:09:57 # 练习:计算某一年的二月份有多少天. # 普通算法:根据年份计算是否是闰年.是:29天,否:28 # 用datetime模块.首先创建出指定年份的3月1号.然后让它往前走一天. year = int(input("请输入年份:")) d = datetime.date(year,3,1) # 创建指定年份的date对象 td = datetime.timedelta(days=1) # 创建一天 的时间段 res = d - td print(res.day)#根据输入的年份,显示 28 或 29
-
os模块:
-
os模块:和操作系统相关的操作被封装到这个模块中,主要是文件删除,目录删除,重命名等操作。(os模块是与操作系统交互的一个接口,它提供的功能多与工作目录,路径,文件等相关)
目录指的是文件夹 。当前目录,工作目录,父级目录:指的都是一个,就是本文件所在的文件夹。
import os #和文件操作相关:重命名,删除 #重命名:文件,目录重命名,目标不能事先存在 os.rename('a.txt','b.txt') #删除: os.remove('b.txt') #删除目录,必须是空目录 os.rmdir('aa') #递归删除空文件夹 os.removedirs('aa') #使用shutil模块可以删除带内容的(非空)目录(慎用)---自动化运维必会 import shutil shutil.rmtree('aa') #和路径相关的属性(了解) os.curdir :当前路径 os.sep :路径分隔符 os.altsep :备用的分隔符 os.extsep :扩展名分隔符 os.pathsep :路径分隔符 os.linesep :行分隔符,不要在写文件的时候,使用这个属性. #和路径相关的操作,被封装到另一个子模块中:os.path 绝对路径: 相对路径: #os.path.dirname(path) 返回一个路径中的父目录部分(不会判断路径是否存在) res = os.path.dirname(r'd:/aaa/bbb/ccc/a.txt') #路径不存在,不会报错 print(res)#d:/aaa/bbb/ccc #os.path.basename(path) 返回path指定的路径的最后一个内容.如果只是一个盘符,或者是以路径分隔符结尾的字符串,则返回空;否则返回的是 路径中的最后一部分内容. res = os.path.basename(r'd:/aaa/bbb/ccc.txt') #路径不存在,不会报错 print(res)#ccc.txt res = os.path.basename(r'd:/aaa/bbb/ccc') print(res)#ccc #os.path.split(path) 返回一个元组(只有两个元素),第二个元素表示的是最后一部分的内容,第一个元素表示的是剩余的内容. 如果只是一个盘符或者是以路径分隔符结尾的字符串,则第二个元素为空。否则第二个元素就是最后一部分的内容。如果path中不包含路径分隔符,则第一个元素为空. res = os.path.split(r'd:/aa/bb/cc/a.txt') #路径不存在,不会报错 print(res)#('d:/aa/bb/cc', 'a.txt') #os.path.join(path,*paths)拼接路径 如果路径中有绝对路径,则在这个路径之前的路径都会被丢弃,而从这个路径开始往后拼接. Windows中盘符一定要带\,否则不认为是一个盘符. path = os.path.join('aaa','bbb','ccc','a.txt') print(path)#aaa\bbb\ccc\a.txt path = os.path.join('d:\\''aaa','bbb','ccc','a.txt') print(path)#d:\aaa\bbb\ccc\a.txt #os.path.abspath(path) 返回一个路径的绝对路径 如果参数路径以/开始,则把当前盘符和参数路径连接起来组成字符串返回 如果参数路径是相对的路径,就把当前路径和参数路径的组合字符串当成结果返回 如果参数路径已经是绝对路径,就直接把参数返回. 注意: 此方法只是简单的将一个拼接好的字符串返回,并不会去检查这个字符串表示的文件是否存在. #如果是/开头的路径,默认是在当前盘符下 res = os.path.abspath(r'/a/b/c') print(res)#D:\a\b\c #参数路径是相对的路径 res = os.path.abspath(r'a/b/c') print(res)#D:\python22\day16\a\b\c res = os.path.abspath('aa') print(res)#D:\python22\day16\aa #参数路径已经是绝对路径 res = os.path.abspath(r'd:\c\aa\bb') print(res)#d:\c\aa\bb #os.path.getsize(path) :获取文件的字节数.如果是文件夹,返回0或者是一个不准确的值 print(os.path.getsize('aa')) # 0 print(os.path.getsize('.')) # 4096 print(os.path.getsize('aa/test.txt')) # 6 #判断功能: #判断是否是绝对路径: print(os.path.isabs('d:/a.txt'))#True 路径不存在,不会报错 print(os.path.isabs('a.txt'))#False #判断是否是目录: print(os.path.isdir('d:/aaa.txt'))#False aaa.txt文件夹不存在 或者 aaa.txt是文件 从文件名不能判断是文件还是目录 print(os.path.isdir('d:/aaa.txt'))#True aaa.txt文件夹存在的情况 #判断路径是否真正存在: print(os.path.exists('d:/a.txt'))#False a.txt不存在 print(os.path.exists('d:/s22/aaa.txt'))#True aaa.txt存在的情况 print(os.path.exists('d:/s22'))#True #判断是否是文件: print(os.path.isfile('d:/aaaa.txt'))#False 文件不存在的情况 print(os.path.isfile('d:/s22'))#False 是目录的情况 print(os.path.isfile('d:/s22/aaa.txt'))#True #【补充】:三颗星是需要记住的。 # 工作目录:在哪个文件下执行的这个py文件,哪一个目录就是你的工作目录 当前执行这个python文件的工作目录相关的工作路径 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 ** os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd ** os.curdir 返回当前目录: ('.') ** os.pardir 获取当前目录的父目录字符串名:('..') ** # 和文件夹相关 os.makedirs('dirname1/dirname2') 可生成多层递归目录 *** os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 *** os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname *** os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname *** os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 ** # 和文件相关 os.remove() 删除一个文件 *** os.rename("oldname","newname") 重命名文件/目录 *** os.stat('path/filename') 获取文件/目录信息 ** # 和操作系统差异相关 os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" * os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" * os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: * os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' * # 和执行系统命令相关 os.system("bash command") 运行shell命令,直接显示 ** os.popen("bash command).read() 运行shell命令,获取执行结果 ** os.environ 获取系统环境变量 ** #示例: import os os.system('dir') ret = os.popen('dir') print(ret.read()) #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模块:和python解释器相关的操作。sys模块是与python解释器交互的一个接口
import sys #sys默认使用os,但是要使用os,还要手动导入。 #获取命令行方式运行的脚本后面的参数:sys.argv[x] sys.argv 在运行python脚本的时候写在python命令后面的是啥,打印出来的就是啥 应用: 在运维里常用的操作方式:所有操作不需要进入程序后再根据提示输入,而是通过命令行的方式完成相关操作。直接在执行文件的时候,给它指令,让它根据指令直接完成一些操作。通过一条命令完成相关操作,使用方便。 #示例1: print('脚本名:',sys.argv[0]) #脚本名:D:\python22\day16\tt16.py print('第一个参数:',sys.argv[1]) #第一个参数: hello print('第二个参数:',sys.argv[2]) #第二个参数: world print(type(sys.argv[1])) #<class 'str'> print(type(sys.argv[2])) #<class 'str'> #示例2: import sys if sys.argv[1] == 'alex' and sys.argv[2] == 'sb': print('登录成功') #sys.path :系统寻找模块的路径. 路径的第一项path[0]始终是调用解释器的脚本所在的路径(相对路径).程序中可以随时对这个路径进行修改.以达到动态添加模块路径的目的. print(sys.path) #sys.modules :返回系统已经加载的模块,以字典形式返回.查看导入了哪些模块 print(sys.modules) #补充: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 *** sys.platform 返回操作系统平台名称
hashlib模块:
-
hashlib模块:封装一些用于加密的类.hashlib模块中提供的类采用的是单向加密算法,也称'哈希算法','摘要算法'
- 加密的目的:用于判断和验证,而并非解密。给一个数据加密,然后用另一个数据加密的结果和第一次加密的结果对比。如果结果相同,说明原文相同.如果不相同,说明原文不同.
-
特点:
- 把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据加密的结果是一致的.
- 单向加密,不可逆.从加密后的结果反推原始数据几乎是不可能的.
- 原始数据的一点小的变化,将导致结果的非常大的差异,'雪崩'效应.
-
给一个数据加密的三大步骤:
例如:md5加密算法:
1.获取一个加密算法对象
2.使用加密对象的update,进行加密,update方法可以调用多次,意味着在前一次的update结果之上,再次进行加密.。参数必须是字节类型
3.通常通过 hexdigest() 获取加密结果 或 digest()方法. 密文:加密的结果
原文:
import hashlib # 获取一个加密对象 m = hashlib.md5() # 使用加密对象的update方法进行加密 ---> 加密结果可以累加 m.update('abc中文'.encode('utf-8')) #对字节进行加密 m.update('def'.encode('utf-8')) m.update(b'def') #在字符串前加b,包含中文时,不能直接在前面加b # 通过hexdigest获取加密结果:字符串形式 res = m.hexdigest() print(res)#2f1b6e294e72d25ae196fe4ac2d27de6 #通过digest获取加密结果 :字节形式 res1 = m.digest() ###通过digest获取加密结果,得到的是字节串 print(res1)#b'/\x1bn)Nr\xd2Z\xe1\x96\xfeJ\xc2\xd2}\xe6' # 不同加密算法(不同的加密对象),实际上就是加密结果的长度不同,长度越长,越耗时.常用的是md5 加密对象除了md5之外,还有如下几种: #'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512','sha512', 'shake_128', 'shake_256' print(len(hashlib.md5().hexdigest()))#32 print(len(hashlib.sha224().hexdigest()))#56 print(len(hashlib.sha256().hexdigest()))#64 # 在创建加密对象时,可以指定参数,称为salt(盐),目的就是为了让加密的结果更加复杂.。 #1: m = hashlib.md5(b'abc') print(m.hexdigest())#900150983cd24fb0d6963f7d28e17f72 #2:同上面是等价的 m = hashlib.md5() m.update(b'abc') print(m.hexdigest())#900150983cd24fb0d6963f7d28e17f72 m = hashlib.md5() m.update(b'abc') m.update(b'def') print(m.hexdigest())#e80b5017098950fc58aad83c8c14978e #注册登录: #注册登录(简版): def get_md5(username,passwd): #加密 m = hashlib.md5(username[::-1].encode('utf-8'))#加盐,将用户名反转,再转化为二进制字节 #m.update(username.encode('utf-8')) m.update(passwd.encode('utf-8')) return m.hexdigest() def register(username,passwd): #注册 res = get_md5(username,passwd) with open('login',mode='at',encoding='utf-8') as f: f.write(res) f.write('\n') def login(username,passwd): #登录 res = get_md5(username, passwd)# 获取当前登录信息的加密结果 with open('login',mode='rt',encoding='utf-8') as f: # 读文件,和其中的数据进行对比 for line in f: if res == line.strip(): return True else: return False while True: op = int(input("1.注册 2.登录 3.退出")) if op == 3 : break elif op == 1: username = input("输入用户名:") passwd = input("输入密码:") register(username,passwd) elif op == 2: username = input("输入用户名:") passwd = input("输入密码:") res = login(username,passwd) if res: print('登录成功') else: print('登录失败')
结构化数据:背后有很多方法、属性支撑着它,如字符串
磁盘上的数据:线性数据(流式数据):数据之间没有引用关系
json模块:
-
json模块:
- JavaScript Object Notation:java脚本对象标记语言.已经成为一种简单的数据交换格式.
- 序列化:将其他数据格式转换成json字符串的过程.
- 反序列化:将json字符串转换其他数据类型的过程.
-
涉及到的方法:
- json.dumps(obj):将obj转换成json字符串返回到内存中. 返回到内存中
- json.dump(obj,fp):将obj转换成json字符串并保存在fp指向的文件中. 序列化到文件中
- json.loads(s):将内存中的json字符串转换成对应的数据类型对象
- json.load(f):从文件中读取json字符串,并转换回原来的数据类型. 从文件中反序列化,在文件中有一个json字符串,进行反序列化
-
注意:
-
json并不能序列化所有的数据类型:例如:set集合 。
-
元组数据类型经过json序列化后,变成列表数据类型。
-
json文件通常是一次性写入,一次性读取,但是可以利用文件本身的方式实现:一行存储一个序列化json字符串,在反序列化时,按行反序列化即可。
-
通常json文件用来保存一些配置信息,这样的配置信息不会太大.通过一次写,一次读,完全可以满足数据交换的需求.
-
-
import json ##序列化: # json.dumps:将数据转换成字符串,用于存储或网络传输。 s = json.dumps([1,2,3]) # 把指定的对象转换成json格式的字符串 print(type(s))#<class 'str'> print(s)#[1, 2, 3] s = json.dumps((1, 2, 3)) # 元组序列化后,变成列表形式的字符串 print(s,type(s)) #[1, 2, 3] <class 'str'> l = json.loads(s) print(l,type(l))#[1, 2, 3] <class 'list'> res = json.dumps(10) print(res,type(res))#10 <class 'str'> res = json.dumps({'name':'alex','age':88}) print(res,type(res))#{"name": "alex", "age": 88} <class 'str'> res = json.dumps(set('abc')) print(res)#TypeError: Object of type 'set' is not JSON serializable # json.dump #将json结果写到文件中 with open('a.txt',encoding='utf-8',mode='a') as f: json.dump([1,2,3],f) #反序列化: #json.loads res = json.dumps([1,2,3]) lst = json.loads(res) ## 反序列化 print(lst,type(lst))#[1, 2, 3] <class 'list'> # 元组会变成列表 res = json.dumps((1,2,3)) lst = json.loads(res) # 反序列化 print(lst,type(lst))#[1, 2, 3] <class 'list'> #json.load #从文件中反序列化: with open('a.txt',encoding='utf-8') as f: res = json.load(f) print(res,type(res))#[1, 2, 3] <class 'list'> # json文件通常是一次性写,一次性读.使用另一种方式,可以实现多次写,多次读. # 把需要序列化的对象.通过多次序列化的方式, 用文件的write方法,把多次序列化后的json字符串写到文件中 with open('json.txt',encoding='utf-8',mode='a') as f: f.write(json.dumps([1,2,3]) + '\n') #此时只能用dumps,不能用dump f.write(json.dumps([4,5,6]) + '\n') # 把分次序列化的json字符串,反序列化回来 with open('json.txt',encoding='utf-8',mode='r') as f: res1 = json.loads(f.readline().strip()) print(res1) res2 = json.loads(f.readline().strip()) print(res2) # [1, 2, 3] # [4, 5, 6] #使用循环改进: with open('json.txt',encoding='utf-8',mode='r') as f: for line in f: res = json.loads(line.strip()) #此时只能用loads,不能用load print(res) # [1, 2, 3] # [4, 5, 6]
-
pickle模块:
-
序列化过程:将Python中所有的数据类型.转换成字节串。
-
反序列化过程:将字节串转换成python中数据类型。
-
pickle常用场景:和json一样,一次性写入,一次性读取。 (可以多次写,多次读)
-
pickle: python专用的序列化模块,和json的方法一致。
-
json,pickle的比较:
-
json:
- 1.不是所有的数据类型都可以序列化.结果是字符串.
- 2.不能多次对同一个文件序列化.
- 3.json数据可以跨语言传输数据
- 4.序列化的结果是字符串
-
pickle:
- 1.所有python类型都能序列化,结果是字节串.
- 2.可以多次对同一个文件序列化
- 3.不能跨语言,只在python中使用
import pickle #python所有的数据类型都可以进行序列化 # 列表序列化 bys = pickle.dumps([1,2,3]) print(bys,type(bys))#b'\x80\x03]q\x00(K\x01K\x02K\x03e.' <class 'bytes'> # 保存了元组的数据类型 bys = pickle.dumps((1,2,3))#序列化 print(bys,type(bys))#b'\x80\x03K\x01K\x02K\x03\x87q\x00.' <class 'bytes'> res = pickle.loads(bys) #反序列化 print(res,type(res))#(1, 2, 3) <class 'tuple'> # 集合序列化,反序列化 bys = pickle.dumps(set('abc')) print(bys,type(bys))#b'\x80\x03cbuiltins\nset\nq\x00]q\x01(X\x01\x00\x00\x00cq\x02X\x01\x00\x00\x00bq\x03X\x01\x00\x00\x00aq\x04e\x85q\x05Rq\x06.' <class 'bytes'> res = pickle.loads(bys) print(res,type(res))#{'c', 'b', 'a'} <class 'set'> # 把pickle序列化内容写入到文件: with open('cc.txt',mode='wb') as f: #转化成字节 pickle.dump([1,2,3],f) # 从文件中反序列化pickle数据 with open('cc.txt',mode='rb') as f: #字节 res = pickle.load(f) print(res,type(res))#[1, 2, 3] <class 'list'> # 多次pickle数据到同一个文件中 with open('cc.txt',mode='ab') as f: pickle.dump([1, 2, 3], f) pickle.dump([1, 2, 3], f) pickle.dump([1, 2, 3], f) pickle.dump([1, 2, 3], f) # 从文件中多次反序列化pickle数据: with open('cc.txt',mode='rb') as f: for i in range(4): res = pickle.load(f) print(res) # [1, 2, 3] # [1, 2, 3] # [1, 2, 3] # [1, 2, 3]
-
collections模块:
-
collections模块:此模块定义了一些内置容器类数据类型之外,可用的集合类数据类型.
-
namedtuple():命名元组。元组的工厂函数
-
deque()双端队列,可以快速的从另外一侧追加和推出对象
-
OrderedDict():有序字典
-
defaultdict():默认值字典.
-
Counter():计数器,主要用来计数 #首字母必须大写
import collections # namedtuple() 所谓的工厂函数指的是:接收类名和一些创建此类对象所需要的一些参数,返回指定类的一个对象.命名元组的特点是给元素绑定了一个有意义的名字.在使用元素时可以使用元素的名字而不必使用索引 第一个参数指定的是返回的子类的类名。第二个参数指定的是子类元组可以拥有的元素名.以字符串组成的列表表示,或者是以空格,逗号分隔的单个字符串都可以。 #用来表示矩形的长和款: Rectangle = collections.namedtuple('Rectangle_class',['length','width']) #'Rectangle_class'为说明信息,不能有空格 r = Rectangle(10,6) # 通过属性访问元组的元素 print(r.length)#10 print(r.width)#6 # 通过索引的方式访问元素 print(r[0])#10 print(r[1])#6 #用来表示一个点的二维坐标: from collections import namedtuple Point = namedtuple('Point', ['x', 'y']) p = Point(1, 2) print(p.x)#1 print(p.y)#2 #类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义: namedtuple('名称', [属性list]): Circle = namedtuple('Circle', ['x', 'y', 'r']) #deque()双端队列,可以快速的从另外一侧追加和推出对象 使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈。deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。 from collections import deque q = deque(['a', 'b', 'c']) q.append('x') q.appendleft('y') print(q)#deque(['y', 'a', 'b', 'c', 'x']) #OrderedDict() 使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用OrderedDict。注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序。 from collections import OrderedDict d = dict([('a', 1), ('b', 2), ('c', 3)]) print(d )# dict的Key是无序的{'a': 1, 'c': 3, 'b': 2} od = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(od) # OrderedDict的Key是有序的 OrderedDict([('a', 1), ('b', 2), ('c', 3)]) #defaultdict:默认字典 # 创建字典的方式: d = {'name':'alex','age':84} print(d)#{'name': 'alex', 'age': 84} d = dict([('name','alex'),('age',84)]) print(d)#{'name': 'alex', 'age': 84} d = { k:v for k,v in [('name','alex'),('age',84)]} print(d)#{'name': 'alex', 'age': 84} # defaultdict() 第一个参数指定的是一个函数名,用来表示当字典对象中出现了不存在的键时,对应的值初始值是如何计算.正因为这个函数是获取值的,所以,对这个函数规定:不能有参数.默认情况下,第一个参数是None,意味着不存在的键对应的值为None. 一旦使用defaultdict 时,指定了不存在的键,则会引发两件事情:1.调用第一个参数指定的函数得到默认值 2.把返回值赋值给这个新键. d = collections.defaultdict(int,name='alex',age=84) print(d['name'])#alex print(d['age'])#84 print(d['addr'])#0 # {'addr':0} 也会被添加到字典 print(d)#defaultdict(<class 'int'>, {'name': 'alex', 'age': 84, 'addr': 0}) d = collections.defaultdict(bool,name='alex',age=84) print(d['name'])#alex print(d['age'])#84 print(d['addr']) #False # {'addr':False} 也会被添加 print(d)# defaultdict(<class 'bool'>, {'name': 'alex', 'age': 84, 'addr': False}) # 可自定义:自定义函数充当其第一个参数,要求自定义函数不能有参数 def f(): return 'hello' d = collections.defaultdict(f,name='Andy',age=20) #第一个参数:函数名 第二,三个是传参:关键字不能加引号 print(d['addr'])#hello print(d)# defaultdict(<function f at 0x000002A685A41E18>, {'name': 'Andy', 'age': 20, 'addr': 'hello'}) # Counter :生成统计信息,用于统计可哈希对象的数量。 是dict的子类.一种特殊的字典.它的键是可哈希对象,值是这个对象的个数统计信息。Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。 c = collections.Counter('asdfgkoiunbbsgfawpag') #括号内为可哈希对象 print(c)#Counter({'a': 3, 'g': 3, 's': 2, 'f': 2, 'b': 2, 'd': 1, 'k': 1, 'o': 1, 'i': 1, 'u': 1, 'n': 1, 'w': 1, 'p': 1}) #显示数量最多的前几名. print(c.most_common(3))#[('a', 3), ('g', 3), ('s', 2)] c = Counter('12435634567') print(c) print(c.most_common(3)) #Counter({'4': 2, '3': 2, '5': 2, '6': 2, '1': 1, '2': 1, '7': 1}) #[('4', 2), ('3', 2), ('5', 2)]
-
-