Python Day 17 常用模块(常用模块一 时间模块,random模块,os模块,sys模块,序列化模块)
时间模块 import time
time.time() 时间戳
time.sleep(1) 休眠一秒
格式化时间(字符串时间) ---》 结构化时间(元组时间) ---》 时间戳时间(浮点型时间)
time.strptime('字符串时间','根据字符串情况自定义时间结构') ---》 time.mktime(结构化时间)
#格式化时间(字符串时间) 2028-5-21 ||| V a = time.strptime('2028-5-21','%Y-%m-%d') #字符串时间转结构化时间 #结构化时间,元组时间 #time.struct_time(tm_year=2028, tm_mon=5, tm_mday=21, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=142, tm_isdst=-1) ||| V b = time.mktime(a) #结构化时间转时间戳时间 #时间戳时间 1842451200.0
时间戳时间(浮点型时间) ---》 结构化时间(元组时间) ---》 格式化时间(字符串时间)
time.localtime(时间戳时间) ---> time.strftime('自定义时间结构',结构化时间)
#时间戳时间 1842451200.0 ||| V a = time.localtime(1842451200.0) #时间戳时间转北京结构化时间 a = time.gmtime(1842451200.0) #时间戳时间转伦敦结构化时间 #结构化时间(元组时间) #time.struct_time(tm_year=2028, tm_mon=5, tm_mday=21, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=142, tm_isdst=0) ||| V b = time.strftime('%Y-%m-%d',a) #结构化时间转字符串时间 #b = time.strftime('%Y-%m-%d',time.localtime(1842451200.0)) #字符串时间 #2028-05-21
#计算时间差 import time def diff_time(oldtime=None,newtime=None,formattime='%Y-%m-%d %H:%M:%S'): if not oldtime or not newtime:return None oldtime_stamp = time.mktime(time.strptime(oldtime,formattime)) newtime_stamp = time.mktime(time.strptime(newtime,formattime)) diff_stamp = abs(newtime_stamp - oldtime_stamp) diff_localtime = time.localtime(diff_stamp) return (diff_localtime.tm_year-1970, diff_localtime.tm_mon-1, diff_localtime.tm_mday-1, diff_localtime.tm_hour, diff_localtime.tm_min, diff_localtime.tm_sec) print(diff_time(newtime='2018-5-22 11:02:50',oldtime='2018-5-21 12:02:50'))
#输入时间月份一号的时间戳 import time import re def time_first(intime): format_intime = re.findall('([1-9]\d{3})-(0[1-9]|[1-2][0-9])',intime) time_stamp = time.mktime(time.strptime('{}-{}-01'.format(format_intime[0][0], format_intime[0][1]), '%Y-%m-%d')) print(time_stamp) return time_stamp print(time.localtime(time_first('2018-03-15 00:10:11')))
random模块 import random
随机小数
random.random() 大于0 小于1之间的小数
random.uniform(1,3) 范围中随机返回小数 (大于1小于3)
随机整数
random.randint(1,5) 大于等于1且小于等于5之间的整数
random.randrange(1,10,2) 同range,顾首不顾尾,设置步长
范围中随机返回
random.choice() 范围中随机选择一个返回
random.sample() 范围中一次性选择多个返回
乱序
random.shuffle() 乱序操作
#随机6位验证码 import random def my_code(): ret = '' for i in range(0,6): code_intstr = str(random.randrange(0,10)) code_alpha1 = chr(random.randint(65,90)) code_alpha2 = chr(random.randint(96,122)) ret += random.choice([code_intstr,code_alpha1,code_alpha2]) return ret print(my_code())
#发红包 import random def red_packets(money=10,number=10): ret = [] surplus = money count = 0 for i in range(number): input('抢红包:') if i == number-1: ret.append(surplus) print('抢到了最后一个{}元红包'.format(surplus)) print('红包发完啦。。。') else: red_packet = random.uniform(0,surplus) while red_packet > money // 3: red_packet = random.uniform(0, surplus) ret.append(red_packet) surplus = surplus - float(red_packet) count+=1 print('抢到了{}元,还剩{}元,剩余{}个红包'.format(red_packet,surplus,number-count)) else: return ret print(red_packets())
os模块 import os
os模块是与操作系统交互的一个接口
import os
print(os.getcwd()) #获取当前目录
os.chdir('C:') #切换目录
print(os.curdir) #当前目录 .
print(os.pardir) #上级目录 ..
os.mkdir() #创建目录
os.makedirs()#多级递归创建
os.remove()#删除
os.rename()#重命名
os.rmdir() #删除单级空目录,如不为空则报错
os.removedirs() #删除文件后,会删除空目录
os.listdir() #列出指定目录下文件,隐藏文件,目录
os.stat() #文件详细信息 *******
os.sep #输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep #输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep #输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name #输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system() #执行系统命令,存在字符编码问题
os.popen() #执行系统命令 os.popen('ifconfig').read() #编码自动转
print(os.environ['path']) #结果字典可以短暂修改
os.walk
import os for root, dirs, files in os.walk(".", topdown=False): for name in files: print(os.path.join(root, name)) for name in dirs: print(os.path.join(root, name)) ========================== top -- 是你所要遍历的目录的地址, 返回的是一个三元组(root,dirs,files)。 root 所指的是当前正在遍历的这个文件夹的本身的地址 dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录) files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录) topdown --可选,为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录(默认为开启)。如果 topdown 参数为 True,walk 会遍历top文件夹,与top 文件夹中每一个子目录。 onerror -- 可选, 需要一个 callable 对象,当 walk 需要异常时,会调用。 followlinks -- 可选, 如果为 True,则会遍历目录下的快捷方式(linux 下是 symbolic link)实际所指的目录(默认关闭)。
os.path
os.path.abspath() #返回绝对路径
os.path.split() #拆分路径 拆分为 除文件名的绝对路径 和文件名
os.path.dirname() #除文件名的绝对路径
os.path.basename() #文件名
os.path.join() #拼接路径,自动使用相对应的分隔符
os.path.isabs()#判断是否绝对路径True False
os.path.isfile()#判断是否是文件True,不能是文件夹False
os.path.isdir()#判断是否是一个存在的目录True,不能是文件False
os._exists()#判断是否存在
os.path.getatime(path) #返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) #返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) #返回path的大小
''' 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 获取系统环境变量 os.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的大小 '''
注意:os.stat('path/filename') 获取文件/目录信息 的结构说明
stat 结构: st_mode: inode 保护模式 st_ino: inode 节点号。 st_dev: inode 驻留的设备。 st_nlink: inode 的链接数。 st_uid: 所有者的用户ID。 st_gid: 所有者的组ID。 st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。 st_atime: 上次访问的时间。 st_mtime: 最后一次修改的时间。 st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。 stat 结构
sys模块 import sys
sys模块是与python解释器交互的一个接口
sys.argv 命令行参数List,第一个元素是程序本身路径,后面sys.argv[1] sys.argv[2] 传参执行,可以进行密码验证
import sys if len(sys.argv) == 3 and sys.argv[1] == 'user' and sys.argv[2] == 'pass': print('ok') else: print('验证失败') exit()
sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称
import sys try: sys.exit(1) except SystemExit as e: print(e) end: print('123')
#计算目录大小 import os import sys sumsize=0 def sum_size(path,size_sum=0): global sumsize if os.path.isdir(path): for i in os.listdir(path): newpath = os.path.join(path,i) sum_size(newpath,sumsize) else: size = os.path.getsize(path) sumsize += size return size_sum if len(sys.argv) == 2: sum_size(sys.argv[1]) print(sumsize) else: sum_size(r'.') print(sumsize)
import os import sys def dir_size(path,size=0): for root,dirs,files in os.walk(path): for i in files: size += os.path.getsize(os.path.join(root,i)) print(size) return size if len(sys.argv) == 2: dir_size(sys.argv[1]) else: dir_size('.')
序列化模块 import json
将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。
比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给? 现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。 但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中。 你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢? 没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串, 但是你要怎么把一个字符串转换成字典呢? 聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。 eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。 BUT!强大的函数有代价。安全性是其最大的缺点。 想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。 而使用eval就要担这个风险。 所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
序列化的目的
json
优点:所有语言通用。
缺点:load不能读取连续的json数据,只能识别单一的json(字典)。
import json
json.dumps(dic) 序列化 内存
json.loads(dic) 反序列化 内存
json.dump(dic) 序列化 文件
json.load(dic) 反序列化 文件
#序列化写入,内存 dic = {'k':'v'} ret = json.dumps(dic) with open('json.txt','w') as f: f.write(ret) #反序列化读取,内存 with open('json.txt') as f: str_dic = f.read() ret2 = json.loads(str_dic) print(ret2) ======================= #序列化写入,文件 dic = {'k':'v'} with open('json2.txt','w') as f: json.dump(dic,f) #反序列化读取,文件 with open('json2.txt') as f: str_dic=json.load(f) print(str_dic)
pickle
优点:几乎可以处理所有的数据类型,可以连续的向文件中dump或者load。
缺点:只有python能够使用。
使用方法与json一致,pickle使用bytes,需要使用b模式
dic = {'k':'v',(1,2,3):{'a','b','c'}} res = pickle.dumps(dic) #序列化 print(res) print(pickle.loads(res)) #反序列化 ======================= dic = {'k':'v',(1,2,3):{'a','b','c'}} with open('pickle.txt','wb') as f: pickle.dump(dic,f) with open('pickle.txt','rb') as f: print(pickle.load(f))
shelve
优点:简单
缺点:不全面,python3中设置文件句柄只读时有bug仍然可以写入。
import shelve f = shelve.open('shelve_file') f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据 f.close() import shelve f1 = shelve.open('shelve_file') existing = f1['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错 f1.close() print(existing) shelve
这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB
import shelve f = shelve.open('shelve_file', flag='r') existing = f['key'] f.close() print(existing)
由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。
import shelve f1 = shelve.open('shelve_file') print(f1['key']) f1['key']['new_value'] = 'this was not here before' f1.close() f2 = shelve.open('shelve_file', writeback=True) print(f2['key']) f2['key']['new_value'] = 'this was not here before' f2.close() 设置writeback
writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。