8.6常用模块
1、时间模块
时间戳、格式化时间、结构化时间
1、时间戳 :从1970年到现在经过的秒数
作用:用于时间间隔的计算
print(time.time()) # 打印时间戳的方法
2、按照某种格式显示的时间(格式化时间)
作用:用于展示时间
print(time.strftime('%Y-%m-%d %H:%M:%S %p')) # %p AM PM 2022-07-08 21:33:42 PM
print(time.strftime('%Y-%m-%d %X')) # 2022-07-08 21:34:45
%y两位数的年份表示(00-99)
%Y四位数的年份表示(000-9999)
%m月份(01-12)
%d月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M分钟数(00=59)
%S秒(00-59)
%a本地简化星期名称
%A本地完整星期名称
%b本地简化的月份名称
%B本地完整的月份名称
%c本地相应的日期表示和时间表示
%j年内的一天(001-366)
%p本地A.M.或P.M.的等价符
%U一年中的星期数(00-53)星期天为星期的开始
%w星期(0-6),星期天为星期的开始
%W一年中的星期数(00-53)星期一为星期的开始
%x本地相应的日期表示
%X本地相应的时间表示
%Z当前时区的名称
%% %号本身
3、结构化时间
作用:可以单独获取当前时间的某一部分#
res=time.localtime()
print(res)
print(res.tm_year) # 2022
print(res.tm_mon,res.tm_hour) # 7 21
print(res.tm_yday) # 189 # 一年的第几日

datetime
作用:可以快速格式化,也可以查询以前的时间
import datetime
print(datetime.datetime.now()) # 现在的时间
print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
print(datetime.datetime.now() +datetime.timedelta(days=-3)) # 三天前
print(datetime.datetime.now() +datetime.timedelta(weeks=2)) # 三周前
时间格式的转换
# struct_time->时间戳 结构化时间转换为时间戳
import time
s_time=time.localtime()
print(time.mktime(s_time))
# 时间戳->struct_time
tp_time=time.time()
print(time.localtime(tp_time))
# 世界标准世界与本地时间
# print(time.localtime())
# print(time.gmtime())
# print(time.localtime(33333))
# print(time.gmtime(333333))
# 结构化时间转换为格式化的字符串形式
# s_time=time.localtime()
# print(time.strftime('%Y-%m-%d %H:%M:%S',s_time))
# 格式化时间转换为结构化时间
print(time.strptime('2000-11-22 11:11:11','%Y-%m-%d %H:%M:%S'))
# 真正需要掌握的只有一条
# !!!真正需要掌握的只有一条:format string<------>timestamp
# '1988-03-03 11:11:11'+7
# format string--->struct_time--->timestamp
# struct_time=time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S')
# timestamp=time.mktime(struct_time)+7*86400
# print(timestamp)
# format string<---struct_time<---timestamp
# res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp))
# print(res)
time.sleep(3)
print(time.asctime())
import datetime
print(datetime.datetime.now())
print(datetime.datetime.utcnow()) # 世界标准时间
# 直接将一个时间戳转换为格式化时间
print(datetime.datetime.fromtimestamp(2222))
2、random模块
import random
print(random.random()) # 得到的值是0-1之间的浮点数
# print(random.randint(1, 3)) # [1,3] 大于等于1且小于等于3之间的整数
# print(random.randrange(1, 3)) # [1,3) 大于等于1且小于3之间的整数
#
# print(random.choice([111, 'aaa', [4, 5]])) # 1或者23或者[4,5]
#
# print(random.sample([111, 'aaa', 'ccc','ddd'],2)) # 列表元素任意2个组合
#
# print(random.uniform(1, 3)) # 大于1小于3的小数,如1.927109612082716
3、OS模块
导入模块
import os
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下为"\r\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
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[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
print(os.path.join("D:\python\wwww","aaa")) #做路径拼接用的 #D:\python\wwww\aaa
print(os.path.join(r"D:\python\wwww","aaa")) #做路径拼接用的 #D:\python\wwww\aaa
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
4、sys模块
sys.argv #在命令行参数是一个空列表,在其他中第一个列表元素中程序本身的路径
sys.exit(0) #退出程序,正常退出时exit(0)
sys.version #获取python解释程序的版本信息
sys.path #返回模块的搜索路径,初始化时使用python PATH环境变量的值
sys.platform #返回操作系统平台的名称
sys.stdin #输入相关
sys.stdout #输出相关
sys.stderror #错误相关
sys.getrecursionlimit() #获取最大递归层数 1000
sys.setrecursionlimit(5000) #设置最大递归层数
5、打印进度条
#=========知识储备==========
#进度条的效果
[# ]
[## ]
[### ]
[#### ]
#指定宽度
print('[%-15s]' %'#')
print('[%-15s]' %'##')
print('[%-15s]' %'###')
print('[%-15s]' %'####')
#打印%
print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义
#可传参来控制宽度
print('[%%-%ds]' %50) #[%-50s]
print(('[%%-%ds]' %50) %'#')
print(('[%%-%ds]' %50) %'##')
print(('[%%-%ds]' %50) %'###')
#=========实现打印进度条函数==========
import sys
import time
def progress(percent,width=50):
if percent >= 1:
percent=1
show_str=('[%%-%ds]' %width) %(int(width*percent)*'#')
print('\r%s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')
#=========应用==========
data_size=1025
recv_size=0
while recv_size < data_size:
time.sleep(0.1) #模拟数据的传输延迟
recv_size+=1024 #每次收1024
percent=recv_size/data_size #接收的比例
progress(percent,width=70) #进度条的宽度70
6、shutil模块
高级的文件,文件夹,压缩包处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
shutil.copyfileobj(open('xmltest.xml','r'), open('new.xml', 'w'))
shutil.copyfile(src, dst)
拷贝文件
shutil.copyfile('b.txt', 'bnew.txt')#目标文件无需存在
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
shutil.copy(src, dst)
拷贝文件和权限
shutil.copy('f1.log', 'f2.log')
shutil.copy2(src, dst)
拷贝文件和状态信息
shutil.copy2('f1.log', 'f2.log')
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除,不想拷贝什么内容
shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。
shutil.move('folder1', 'folder3')
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
创建压缩包并返回文件路径,例如:zip、tar
base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如 data_bak =>保存至当前路径
如:/tmp/data_bak =>保存至/tmp/
format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要压缩的文件夹路径(默认当前目录)
owner: 用户,默认当前用户
group: 组,默认当前组
logger: 用于记录日志,通常是logging.Logger对象
# 将 /data 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
# 将 /data下的文件打包放置 /tmp/目录
import shutil
ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
#shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
#zipfile压缩解压缩
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()
# 解压
z = zipfile.ZipFile('xh.zip', 'r')
z.extractall(path='.')
z.close()
#tarfile压缩解压缩
import tarfile
# 压缩
t=tarfile.open('/tmp/egon.tar','w')
t.add('/test1/a.py',arcname='a.bak')
t.add('/test1/b.py',arcname='b.bak')
t.close()
# 解压
t=tarfile.open('/tmp/egon.tar','r')
t.extractall('/egon')
t.close()
序列化与反序列化
1、什么是序列化与反序列化
序列化指的是把内存的数据类型转换成一个特定的格式的内容
该格式内容可用于存储或者传输给其他平台使用# 特定的格式 :json格式或者pickle格式
反序列化:特定的格式通过反序列化转换成内存中的数据类型
2、为什么要用序列化
序列化得到的特定格式的内容有两种用途:
a.可用于存储=》存档
应该是一种专用的格式,picker只有Python用
b.传输给其他平台使用=》跨平台数据交互
应该是一种通用,json格式,能够被所有的语言识别
json格式下序列化和反序列化
# json格式化下
import json
# res=json.dumps(True)
res=json.dumps([1,'aaa',True,False]) # [1, "aaa", true, false] # 这就是json格式
print(res,type(res))
# json反序列化
l = json.loads(res) # [1, 'aaa', True, False]
print(l)
写入到文件中
import json
# res=json.dumps(True)
res=json.dumps([1,'aaa',True,False]) # [1, "aaa", true, false] # 这就是json格式
print(res,type(res))
with open('text.json',mode='wt',encoding='utf-8')as f:
f.write(res)
# 将序列化的结果写入文件的简单方法
with open('text.json',mode='wt',encoding='utf-8')as f:
json.dump([1,'aaa',True,False],f)
从文件中反序列化
with open('text.json',mode='rt',encoding='utf-8')as f:
json_res=f.read()
l=json.loads(json_res)
print(l)
# 将文件读取json格式的字符串反序列化的简单方法
with open('text.json',mode='rt',encoding='utf-8')as f:
l=json.load(f)
print(l)
# json验证:json格式兼容的是所有语言的通用的数据,不能识别某一语言的独有类型
# json格式的字符串用双引号
# 中文也可以装换成json格式
# import json
# res=json.dumps({'k1':'好好说'}) # {"k1": "\u597d\u597d\u8bf4"}
# print(res)
猴子补丁
猴子补丁的核心就是用自己的代码替代所用模块的源代码
# 在入口处打猴子补丁
# import json
# import ujson
#
# def monkey_patch_json():
# json.__name__ = 'ujson'
# json.dumps = ujson.dumps
# json.loads = ujson.loads
#
# monkey_patch_json() # 在入口文件出运行
pickle模块
import pickle
# res=pickle.dumps({1,2,3,4,5})
# print(res,type(res))
# s=pickle.loads(res)
# print(s,type(s))
xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单
configparser模块
[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31
[section2]
k1 = v1
# 读取
import configparser
config = configparser.ConfigParser()
config.read('a.cfg')
# 查看所有的标题
res = config.sections() # ['section1', 'section2']
print(res)
# 查看标题section1下所有key=value的key
options = config.options('section1')
print(options) # ['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
# 查看标题section1下所有key=value的(key,value)格式
item_list = config.items('section1')
print(
item_list) # [('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
# 查看标题section1下user的值=>字符串格式
val = config.get('section1', 'user')
print(val) # egon
# 查看标题section1下age的值=>整数格式
val1 = config.getint('section1', 'age')
print(val1) # 18
# 查看标题section1下is_admin的值=>布尔值格式
val2 = config.getboolean('section1', 'is_admin')
print(val2) # True
# 查看标题section1下salary的值=>浮点型格式
val3 = config.getfloat('section1', 'salary')
print(val3) # 31.0
"""
改写
"""
import configparser
config = configparser.ConfigParser()
config.read('a.cfg', encoding='utf-8')
# 删除整个标题section2
config.remove_section('section2')
# 删除标题section1下的某个k1和k2
config.remove_option('section1', 'k1')
config.remove_option('section1', 'k2')
# 判断是否存在某个标题
print(config.has_section('section1'))
# 判断标题section1下是否有user
print(config.has_option('section1', ''))
# 添加一个标题
config.add_section('egon')
# 在标题egon下添加name=egon,age=18的配置
config.set('egon', 'name', 'egon')
# config.set('egon','age',18) #报错,必须是字符串
# 最后将修改的内容写入文件,完成最终的修改
config.write(open('a.cfg', 'w'))
# 修改
import configparser
config = configparser.ConfigParser()
config.read('a.cfg', encoding='utf-8')
# 删除整个标题section2
config.remove_section('section2')
# 删除标题section1下的某个k1和k2
config.remove_option('section1', 'k1')
config.remove_option('section1', 'k2')
# 判断是否存在某个标题
print(config.has_section('section1'))
# 判断标题section1下是否有user
print(config.has_option('section1', ''))
# 添加一个标题
config.add_section('egon')
# 在标题egon下添加name=egon,age=18的配置
config.set('egon', 'name', 'egon')
# config.set('egon','age',18) #报错,必须是字符串
# 最后将修改的内容写入文件,完成最终的修改
config.write(open('a.cfg', 'w'))
"""
基于上述方法添加一个ini文档
"""
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9'}
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
config.write(configfile)