常用模块介绍
常用模块的介绍:
time,datetime
os,sys
hashlib,json,pickle,collections
time模块:
time 模块(和时间相关):封装了获取时间戳和字符串形式的时间的一些方法。
-
三大对象:时间戳, 结构化时间对象(9大字段), 字符串【重点】
time.time():获取时间戳
time.gmtime([seconds]):获取格式化时间对象:是九个字段组成的
time.localtime([seconds]):获取格式化时间对象:是九个字段组成的
time.mktime(t):时间对象 -> 时间戳
time.strftime(format[,t]):把时间对象格式化成字符串
-
time.strptime(str,format):把时间字符串转换成时间对象
import time # 获取时间戳 # 时间戳:从时间元年(1970 1 1 00:00:00)到现在经过的秒数。 print(time.time())#1558317680.919616 # 获取格式化时间对象:是九个字段组成的。 # 默认参数是当前系统时间的时间戳。 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 # 格式化时间对象转换成字符串 s = time.strftime("%y %m %d %h:%m:%s") print(s,type(s))#2019 05 20 10:05:17 <class 'str'> # 把时间字符串转换成时间对象 time_obj = time.strptime('2019 05 20','%y %m %d') 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模块:和操作系统相关的操作被封装到这个模块中,主要是文件删除,目录删除,重命名等操作。
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.path #返回一个路径中的父目录部分(不会判断路径是否存在) res = os.path.dirname(r'd:/aaa/bbb/ccc/a.txt') #路径不存在,不会报错 print(res)#d:/aaa/bbb/ccc #返回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 #返回一个元组,第二个元素表示的是最后一部分的内容,第一个元素表示的是剩余的内容. 如果只是一个盘符或者是以路径分隔符结尾的字符串,则第二个元素为空。否则第二个元素就是最后一部分的内容。如果path中不包含路径分隔符,则第一个元素为空. res = os.path.split(r'd:/aa/bb/cc/a.txt') #路径不存在,不会报错 print(res)#('d:/aa/bb/cc', 'a.txt') #拼接路径 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 #返回一个路径的绝对路 如果参数路径是相对的路径,就把当前路径和参数路径的组合字符串当成结果返回. 如果参数路径已经是绝对路径,就直接把参数返回. 如果参数路径以/开始,则把当前盘符和参数路径连接起来组成字符串返回. 注意: 此方法只是简单的将一个拼接好的字符串返回,并不会去检查这个字符串表示的文件是否存在. #如果是/开头的路径,默认是在当前盘符下 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 #判断功能: #判断是否是绝对路径 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
sys模块:
-
sys模块:和python解释器相关的操作
import sys #获取命令行方式运行的脚本后面的参数:sys.argv[x] 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'> # 解释器执行时寻找模块的路径:sys.path #sys.path :系统寻找模块的路径. print(sys.path) #sys.modules :返回系统已经加载的模块,以字典形式返回. print(sys.modules)
hashlib模块:
-
hashlib模块:封装一些用于加密的类.
- 加密的目的:用于判断和验证,而并非解密。给一个数据加密,然后用另一个数据加密的结果和第一次加密的结果对比。如果结果相同,说明原文相同.如果不相同,说明原文不同.
- 特点:
- 把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据加密的结果是一致的.
- 单向加密,不可逆.
- 原始数据的一点小的变化,将导致结果的非常大的差异,'雪崩'效应.
-
给一个数据加密的三大步骤:
例如:md5加密算法:
1.获取一个加密对象
2.使用加密对象的update,进行加密,update方法可以调用多次
3.通常通过 hexdigest() 获取加密结果 或 digest()方法.import hashlib # 获取一个加密对象 m = hashlib.md5() # 使用加密对象的update进行加密 m.update('abc中文'.encode('utf-8')) #????? m.update('def'.encode('utf-8')) # 通过hexdigest获取加密结果 res = m.hexdigest() res1 = m.digest() ###???? print(res)#2f1b6e294e72d25ae196fe4ac2d27de6 print(res1)#b'/\x1bn)nr\xd2z\xe1\x96\xfej\xc2\xd2}\xe6' # 不同加密算法(不同的加密对象),实际上就是加密结果的长度不同,长度越长,越耗时.常用的是md5 print(len(hashlib.md5().hexdigest()))#32 print(len(hashlib.sha224().hexdigest()))#56 print(len(hashlib.sha256().hexdigest()))#64 # 在创建加密对象时,可以指定参数,称为salt. m = hashlib.md5(b'abc') print(m.hexdigest())#900150983cd24fb0d6963f7d28e17f72 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,password): m = hashlib.md5(username[::-1].encode('utf-8'))#加盐,将用户名反转,再转化为二进制字节 # m.update(username.encode('utf-8')) m.update(password.encode('utf-8')) ret = m.hexdigest() return ret def regist(username,password): res = get_md5(username,password)#加密 with open('login',encoding='utf-8',mode='r') as f: ???????
序列化:把内存中的数据,转换成字节或字符串的形式,以便于进行存储或者网络传输.??????
内存中数据 -----> 字节串/字符串 : 序列化
字节串/字符串 ----> 内存中的数据 : 反序列化
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并不能序列化所有的数据类型:例如:set集合 。
元组数据类型经过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)#[1, 2, 3] 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数据可以跨语言
-
pickle:
- 1.所有python类型都能序列化,结果是字节串.
- 2.可以多次对同一个文件序列化
- 3.不能跨语言.
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():命名元组
defaultdict():默认值字典.
-
counter():计数器 #首字母必须大写
import collections # namedtuple() rectangle = collections.namedtuple('rectangle_class',['length','width']) r = rectangle(10,6) # 通过属性访问元组的元素 print(r.length)#10 print(r.width)#6 # 通过索引的方式访问元素 print(r[0])#10 print(r[1])#6 #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() 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 :计数器 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)]
下一篇: 浅谈linux线程切换问题