1、import time
time模块与时间相关的功能
在python中时间分为3种
1.时间戳timestamp从1970 1月 1日到现在的秒数 主要用于计算两个时间的差
2.localtime 本地时间 表示的是计算机当前所在的位置
3.UTC世界协调时间
时间戳 结构化 格式化字符
#获取时间戳 返回浮点型
print(time.time())
#获取当地时间 返回的是结构化时间
print(time.localtime())
#获取UTC时间 返回的还是结构化时间 比中国时间少8小时
print(time.gmtime())
#获取的时间转成我们期望的格式 仅支持结构化时间
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))
#获取格式化字符串的时间转为结构化时间 注意:格式必须匹配
print(time.strptime('2018-08-09 09:01:22','%Y-%m-%d %H:%M:%S'))
#时间戳 转结构化
print(time.localtime(time.time()))
#结构化转 时间戳
print(time.mktime(time.locatime()))
常用的format格式:
1 %a 本地(local)简化星期名称 2 %A 本地完整星期名称 3 %b 本地简化月份名称 4 %B 本地完整月份名称 5 %c 本地相应的日期和时间表示 6 %d 一个月中的第几天(01-31) 7 %H 一天中的第几个小时(24小时制,00-23) 8 %l 一天中的第几个小时(12小时制,01-12) 9 %j 一年中的第几天(01-366) 10 %m 月份(01-12) 11 %M 分钟数(00-59) 12 %p 本地am或者pm的相应符 13 %S 秒(01-61) 14 %U 一年中的星期数(00-53,星期天是一个星期的开始,第一个星期天之前的所有天数都放在第0周) 15 %w 一个星期中的第几天(0-6,0是星期天) 16 %W 和%U基本相同,不同的是%W以星期一为一个星期的开始 17 %x 本地相应日期 18 %X 本地相应时间 19 %y 去掉世纪的年份(00-99) 20 %Y 完整的年份 21 %z 用+HHMM或者-HHMM表示距离格林威治的时区偏移(H代表十进制的小时数,M代表十进制的分钟数) 22 %Z 时区的名字(如果不存在为空字符) 23 %% %号本身 24 %p只有与%I配合使用才有效果 25 当使用strptime()函数时,只有当在这年中的周数和天数被确定的时候%U和%W才会被计算
2、import datetime
1.#获取时间,获取当前时间,并返回的是格式化字符时间
print(datetime.datetime.now())
2.#单独获取某个时间,年,月,日等
d=datetime.datetime.now() print(d.year) print(d.day)
3.#手动指定时间
d2=datetime.datetime(2018,10,15,9,50,00) print(d2)
4.#计算两个时间的差 :只能减-,不能加+
print(d-d2)
5.#替换某个时间
print(d.replace(year=2010))
6.#表示时间差的模块:timedelta
print(datetime.timedelta(days=1))
t1=datetime.timedelta(days=1)
t2=datetime.timedelta(weeks=1)
print(t2-t1)
7.#时间差可以和一个datetmie进行加减
print(d+t2)
str类型的日期转换为时间戳
# 字符类型的时间 tss1 = '2013-10-10 23:40:00' # 转为时间数组 timeArray = time.strptime(tss1, "%Y-%m-%d %H:%M:%S") print timeArray # timeArray可以调用tm_year等 print timeArray.tm_year # 2013 # 转为时间戳 timeStamp = int(time.mktime(timeArray)) print timeStamp # 1381419600 # 结果如下 time.struct_time(tm_year=2013, tm_mon=10, tm_mday=10, tm_hour=23, tm_min=40, tm_sec=0, tm_wday=3, tm_yday=283, tm_isdst=-1) 2013 1381419600
更改str类型日期的显示格式
tss2 = "2013-10-10 23:40:00" # 转为数组 timeArray = time.strptime(tss2, "%Y-%m-%d %H:%M:%S") # 转为其它显示格式 otherStyleTime = time.strftime("%Y/%m/%d %H:%M:%S", timeArray) print otherStyleTime # 2013/10/10 23:40:00 tss3 = "2013/10/10 23:40:00" timeArray = time.strptime(tss3, "%Y/%m/%d %H:%M:%S") otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray) print otherStyleTime # 2013-10-10 23:40:00
时间戳转换为指定格式的日期
# 使用time timeStamp = 1381419600 timeArray = time.localtime(timeStamp) otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray) print otherStyleTime # 2013--10--10 23:40:00 # 使用datetime timeStamp = 1381419600 dateArray = datetime.datetime.utcfromtimestamp(timeStamp) otherStyleTime = dateArray.strftime("%Y--%m--%d %H:%M:%S") print otherStyleTime # 2013--10--10 15:40:00
获取当前时间并且用指定格式显示
# time获取当前时间戳 now = int(time.time()) # 1533952277 timeArray = time.localtime(now) print timeArray otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray) print otherStyleTime # 结果如下 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=11, tm_hour=9, tm_min=51, tm_sec=17, tm_wday=5, tm_yday=223, tm_isdst=0) 2018--08--11 09:51:17 # datetime获取当前时间,数组格式 now = datetime.datetime.now() print now otherStyleTime = now.strftime("%Y--%m--%d %H:%M:%S") print otherStyleTime # 结果如下: 2018-08-11 09:51:17.362986 2018--08--11 09:51:17
3、import random
random :随机数相关模块
random 0-1 开闭
randint 0-3 开开
randrange 0-3 开闭
choice [1,2,4,5,6,'哈哈']随机选择一个
sample([1,2,4,5,6,'哈哈'])随机选择2个
uniform(1,3)闭闭 浮点
shuffle(列表)打乱顺序
print(random.random()) print(random.randint(1,3)) print(random.randrange(1,2,3)) print(random.sample([1,2,3],2)) li=[1,2,3,4,5] print(random.shuffle(1)) print(1) print(random.uniform(1,2)) #随机验证码功能 def make_code(i): res='' for j in range(i): #获取0到9随机数 num=str(random.randint(0,9) #获取A-Z随机字母 letter=chr(random.randint(65,90) #随机获取数字或字母 group=random.choice([num,letter]) res+=group return res print(make_code(i))
4、import shutil
shutil 模块:用于简化文件操作(文件的高级操作)
常用方法:copy move rm make_archive
1.利用shutil来创建压缩文件,仅支持tar和zip格式,内部调用zipFile模块实现
shutil.make_archive('test','zip',root_dir='path')
2.解压zip
z=zipfile.ZipFile(path)
z.extractall()
z.close()
3.解压tar
t=tarfile.open(path) t.extractall() t.close() t=tarfile.open(path) t.add(path) t.close()
5、import json
pickle 产生的数据只能由python读取(跨平台性差)
开发程序不可能就是单机程序,需要和其他设备,其他的平台交换数据
一三八四三八零零四三八
我们需要找到一种通用的数据格式,让各个平台都能识别
json模块:
用于处理json格式数据的模块
json全称javascrip objiect notation js的对象表示法
所以json能支持的数据类型就是js支持的数据类型
json格式标准
能存储的有 str int flost dic list bool
案列:要求数据的最开始和最末尾必须是{}[]
{'name':'yxx'}
json是一种通用的数据交换格式,目前主流的语言都能够轻松解析
注意:在使用json格式的时候,数据类型必须按照要求来写,并且不支持python元组
常用方法:
序列化:
dump 处理文件
dumps 处理字符串
反序列化:
load 处理文件
loads 处理字符串
1.将python格式的数据序列化为json格式,python中的任何类型都能被转化为json格式,表现形式不同
import json user={'name':"音乐会","age":20,"hobbies":("music","movies")} print(json.dumps(users)) json.dump(user,open("users.json","wt",encoding="utf-8"))
2.json反序列化
jsonstr=json.load(open("users.json","r",encoding="utf-8")) print(jsonstr)
3.其他
# 解决序列化的编码问题 info={"爱好":"赚钱"} json_info=json.dumps(info,ensure_ascii=False) print(json_info)
6、import sys
sys模块:一般用于设计脚本程序
常用:argv:获取cmd输入的参数
import sys print(sys.argv) #获取系统内核版本号 print(sys.platform) #退出系统 print(sys.exit(0))
7、import os
os模块:表示操作系统
#获取项目主目录 print(os.path.dirname(os.path.dirname(__file__))) print(os.path.normpath(os.path.join(os.getcwd(),os.pardir)))
#获取操作系统内核版本
print(os.name)
#获取当前执行文件目录内的所有文件夹名和文件名 print(os.system('dir'))
#获取操作系统的环境变量,返回的是字典形式 print(os.environ)
#获取当前的工作目录
print(os.getcwd())
#切换工作目录
os.chdir(file)#file文件路径
#当前目录,一个点
print(os.curdir)
#当前目录 两个点
print(os.pardir)
#创建目录,可用递归创建
print(os.makedirs('a/b/c'))
#创建一个目录
print(os.mkdir())
#删除目录,递归删除,如果没有文件就删除,有文件就保留
print(os.removedirs('a/b/c'))
#删除一个目录
print(os.remdir())
#删除文件,仅能删除文件
print(os.remove())
#列出所有文件和文件名:
print(os.listdir())
#获取当前平台的路径分隔符
print(os.sep)
#获取当前换行符
print(os.linesep)
#返回绝对路径 print(os.path.abspath('bb.txt')
#路径拼接 print(os.path.join('c:','user','a.txt'))
#斜杠会修改为当前平台的分隔符,可用来执行..来返回上一级 print(os.path.normpath(r'acd..'))
#将路径拆分为文件夹路径和文件名称
print(os.path.split())
#获取路径中的上一级
print(os.path.dirname(__file__)
#获取最后一级名称
print(os.path.basename())
#判断路径是否存在
print(os.path.exists())
#判断是否是绝对路径
print(os.path.isabs())
#大写变小写,斜杠根据当前平台修改
print(os.path.normacase())
8、import pickle
pickle模块:用于序列化
序列化就是将内存中的数据持久化到硬盘中
回顾:使用文件读写也能完成把数据持久化存储,但是有局限性,当数据比较复杂时用起来就很麻烦
列如:需要把一个字典存储到硬盘中,先转成字符串,再写入,读取为字符串,再转为原始的格式
所以就有了pickle
1.能将所有python中的数据序列化 int float str dic list tuple set bool
2.反序列化,将之前序列化的数据,在恢复成python的数据格式
pickle产生的数据,只能由python读取(跨平台性差)
今后你开发程序不可能就是单机程序,你需要和其他设备,其他平台,交换数据
一三八四三八零零四三八
我们需要找到一种通用的数据格式,让各个平台都能识别
users = {"name":"yyh","age":20,"hobbies":["打豆豆","飘"]} import pcikle 序列化 print(pickle.dumps(users)) f=open("p.txt","wb") f.write(pickle.dumps(users)) f.close() 反序列化 f=open("p.txt","rb") print(pickle.loads(f.read())) f.close()
9、import xml
xml模块:就是可扩展的标记语言
为了能够在不同的平台间继续数据的交换
为了使交换的数据能让对方看懂,就需要按照一定的语法规范来书写
xml语法格式:
1、任何的起始标签都必须有一个结束标签
<tagname></tagname/>
<tagname></tagname/>
<tagname/>简化书写
2、可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签,这种语法是在大于符号之前紧跟一个斜线(/),列如<百度百科词条/>,xml解析器会将其翻译成<百度百科词条></百度百科词条>
3、标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,列如这是一串百度百科中的样列字符串,这好比是将起始和结束标签看做是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号
<tag1>
<tag2>
<tag3>
</tag3>
</tag2>
</tag1>
重点:关闭标签应该从内往外,一层一层关闭,顺序不能乱
4、所有的特性都必须在值的周围加上双引号
注意:最外层有且只有一个标签,这个标签称之为根标签
第一行应该有文档说明,用于高速计算机怎么理解
列如:<?xml version="1.0" encoding="utf-8"?>
当标签嵌套的时候会出现层级关系,如果一个标签不被任何别的标签包裹,那他就是根标签(最外层)
使用场景:
1.配置文件
2.常规的数据交换,列如从服务器获取一段新闻
与json的区别
作用是一样的,都是一种数据格式
xml比json先诞生
json的数据比xml小
目前json是主流
python中的xml处理
使用到的模块
Elment Tree 表示整个文件的元素树
Elment 表示一个节点
属性
1.text 开始标签和结束标签中间的文本
2.attrib 所有的属性 字典类型
3.tag 标签的名字
方法
get 获取某个属性的值
1.解析xml
查找标签
find 在子标签中获取名字匹配第一个
findall 在子标签中获取名字匹配的所有标签
iter(tagname) 在全文中查找匹配的所有标签,返回一个迭代器
2.生成xml
用Elment Treee
parse() 解析一个文件
getroot() 获取根标签
write() 写入到文件
3.修改xml
set 修改或删除一个属性
remove 删除一个标签
append 添加一个标签
读取xml文档到内存中,得到一个包含所有数据的节点树 每一个标签就称之为一个节点或元素 tree=et.parse('text.xml') 获取根标签 root=tree.getroot() 获取所有的子标签,找的是第一个 print(root.find('标签名')) 找的是所有 print(root.findall('标签名')) 获取元素 print(root.iter('标签名')) for i in root.iter('标签名')) print(i) 遍历整个xml for i in root: print(i.tag,i.attrib,i.text) for j in i: print(j.tag,j.attrib,j.text)
读取到内存 tree=et.parse('text.xml') 添加子标签 newtag=et.Element('newTag') 文本 newtag.text='123' 属性 newtag.attrib['name']='skk' 添加 i.append(newtag) 写回内存 tree.write("text.xml",encoding="utf-8",xml_declaration=False)
10、import shelve
shelve模块:也是一种序列化
常用使用方法:
1.open()读写
2.close()关闭
特点:使用方法比较简单,提供一个文件名就可以开始读写
读写的方法和字典一致
你可以把它当成带有自动序列化功能的字典
原理:内部使用的就是pickle 所以也存在跨平台性差的问题
使用情况:写一个单机程序可以考虑
import shelve 序列化 s=shelve.open('shelvetest.txt') s['data']='内容' s['data']['name']='maple' 反序列化 s1=shelve.open('shelvetest.txt') print(s1.get('name')) s1.close()
11、import configParser
configparser就是配置文件解析模块
配置文件:用于提供程序运行所需的一些信息的文件,后缀 ini cfg
作用:方便用户修改,列如超时时间
配置文件内容格式:
只包括两种元素
section 分区
option 选项
一个文件可以有多个section
一个section可以有多个选项
核心功能:
1.section 获取所有分区
2.option 获取所有选项
3.get 获取选项的值 需要传入section option
注意:大小写不敏感
假装做一个下载功能,最大链接速度可以由用户来控制,用户不会看代码,所以提供一个配置文件 得到配置文件对象 cfg=configparser.ConfigParser() 读取一个配置文件 cfg.read('download.ini') print(cfg.section()) print(cfg.option('sectionl')) print(cfg.get('sectionl','maxspeed')) print(cfg.getint('sectionl','minspeed')) 修改最大速度为1024 cfg.set('sectionl','maxspeed','1024') cfg.write(open("download.ini","w",encoding="utf-8"))
12、import hashlib
hash模块:就是一种算法。
用于将任意长度的数据,压缩映射到一段固定长度的字符(提取特征)
hash的特点:
1.输入数据不同,得到的hash值有可能相同
2.不能通过hash值来得到输入的值
3.如果算法相同,无论输入的数据长度是多少,得到的hash值长度相同
用途:
因为以上特点常将hash算法用于加密和文件校验
输入用户名和密码,在代码中与数据库中的判断是否相同
思考当你的数据需要在网络中传统时,就可能会受到网络攻击
黑客通过抓包工具就能截获你发送和接受的数据
所以你的数据,如果涉及到隐私,就应该先加密再发送
加密的方式有很多:常用的MD5就是一种hash算法
常用的提升安全性的手段就是加盐:就是把你加密前的数据做一些改动,列如把顺序反过来
import hashlib md=hashlib.md5() md.update("hello你这么牛逼吗 你破解我试试? DSB".encode("utf-8")) print(md.hexdigest()) 破解MD5可以尝试撞库,原理:有一个数据库里面存放了常见的明文和密文的对应关系 所以我们可以拿来一个密文取数据库中查找,有没有已经存在的明文,看运气能不能撞库成功 假设我们已经拿到了一个众多账号中的一个密码,我可以拿这个密码挨个测试你所有账号,看能不能碰到运气 pwd_dic = {"123456":"e10adc3949ba59abbe56e057f20f883e","hello":"5d41402abc4b2a76b9719d911017c592"} for i in pwd_dic: if pwd_dic[i] == "5d41402abc4b2a76b9719d911017c592": print(i) 今后我们在写一些需要网络传输的程序时,如果要进行加密,最好把加密的算法搞得更复杂 密码长度为6位 abcdef 在前面加一个abc 在后面加一个cba完事以后再加密 pwd='abcdef' pwd='abc'+'abcdef'+'cba' md2=hashlib.md5() md2.update(pwd.encode.('utf-8')) print(md2.hexdigest()) 加密实际上能做的就是让黑客的破解成本大于他的利润 #强制要求你进行加盐加密 import hmac h = hmac.new("121212".encode("utf-8")) h.update("abcd".encode("utf-8")) print(h.hexdigest())
13、import logging
logging模块:
1、控制日志级别
2、控制日志格式
3、控制输出的目标为文件
控制日志级别犹如火警的级别
logging.debug()
logging.info()
logging.warning()
logging.error()
logging.critical()
一级 大功率电器
二级 抽烟
三级 自焚
四级 渣药包
import logging 1.#拿到logger对象 logger1=logging.getLogger('maple') 2.#设置handler对象,指定日志输入目标位置(文件或终端) fh1=logging.FileHandler('a1.log',encoding='utf-8')#文件 ch=logging.StreamHandler()#终端 3.#设置formatter对象 formatter1=logging.Formatter( fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p' ) 4.#绑定logger对象与handler对象 logger1.addHandler(fh1) logger1.addHandler(ch) 5.#绑定handler对象与formatter对象 fh1.setFormatter(formatter1) 6.#设置日志级别,有logger对象与handler对象两层关卡, # 必须都放行最终日志才会放行,通常二者级别相同 logger1.setLevel(10) fh1.setLevel(10) ch.setLevel(10) 7.#使用logger对象产生日志 logger1.info('maple get $100 million')
logging的配置字典,方便使用
standard_format = '%(asctime)s - task:%(name)s - %(filename)s:%(lineno)d -' ' %(levelname)s : [%(message)s]' simple_format = '%(filename)s:%(lineno)d - %(levelname)s : [%(message)s]' fh1_path = r'a1.log' fh2_path = r'a2.log' # log配置字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { #打印到终端的日志 'ch': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到终端 'formatter': 'simple' }, #打印到a1.log文件的日志 'fh1': { 'level': 'DEBUG', 'class': 'logging.FileHandler', # 保存到文件 'formatter': 'standard', 'filename': fh1_path, # 日志文件的路径 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, # 打印到a2.log文件的日志 'fh2': { 'level': 'DEBUG', 'class': 'logging.FileHandler', # 保存到文件 'formatter': 'simple', 'filename': fh2_path, # 日志文件的路径 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { '': { 'handlers': ['fh1', 'fh2', 'ch'], 'level': 'DEBUG', }, }, }
14、import re
re模块:就是正则表达式
是一些带有特殊含义的符号或者符号的组合
它的作用是对字符串进行过滤
在一堆字符串中找到你所关心的内容
你就需要告诉计算机你的过滤规则是什么样的,通过什么方式来告诉计算机?就是通过正则表达式
第一步:学习正则表达式,各种符号所表示的含义
re模块的内部实现,不是python,而是调用了c库
#待处理的字符串 src = "abcdef 12121gaa1a _ - a * / a" #在字符串中查找所有满足条件的 print(re.findall('ab',src)) #w字母数字下划线 W非字母数字下划线 与前面相反 print(re.findall('w',src)) print(re.findall('W',src)) #s所有不可见字符 S可见字符 print(re.findall("s",src)) print(re.findall("S",src)) # d 所有数字 D所有非数字 print(re.findall("d",src)) print(re.findall("d",src) # 特殊字符直接匹配 print(re.findall(" ",src)) print(re.findall(" ",src)) # . (点)除了 以外任意字符 print(re.findall(".",src)) #匹配重复字符 * + ?{} #*前面的表达式出现任意次 print(re.findall("wd*","1 12 aa")) #+重复1次或多次 print(re.findall("d+","1 12121272163871asas6378232678a aa")) #?表示重复0次或1次 print(re.findall("d?","aa bb a1c 1c1 123")) #{m,n}最少m次,最多n次 print(re.findall('d{1,3}','1 23 123 1234')) #{m}必须是m次 print(re.findall('[a-z]{,3}','a aa aaa aaaa aaaalaaa')) ## 从字符串1982asasa中找到所有0 1 2,需使用匹配范围 print(re.findall("0|1|2","1982asasa")) #[]字符集合 括号内的符号不是整体 print(re.findall('[012]','1982asasa')) # 在这里表示除了0-9之外的任意字符 print(re.findall("[^0-9]","1982asasa")) # 请找出 所有的数字0-9和字母a-z A-Z # 注意 减号只有在两个字符中间才有范围的意思 在两边都是普通字符 print(re.findall("[0-9a-zA-Z]","1982asa+sa")) # ^ 匹配行首 print(re.findall("^h","hellohello")) # $ 匹配行未 注意写在表达式后面 print(re.findall("[a-z]oh$","lohhel9ohelloh")) # 单词边界 指的是单词的末尾 print(re.findall("h\b","helloh hih")) print(re.findall("h\B","hellhoh hih")) # 贪婪匹配 * + 不是固定的特殊符号 只是一种现象 # 会一直匹配到不满足条件为止 用问号来阻止贪婪匹配(匹配最少满足条件的字符数) print(re.findall("w+?","ajshsjkdsd")) print(re.findall("w*?","ajshsjkdsd")) src = "<img src='www.baidupic.shuaiqi1.jpg'><img src='www.baidupic.shuaiqi2.jpg'><img src='www.baidupic.shuaiqi3.jpg'>" # () 用于给正则表达式分组(group) 不会改变原来的表达式逻辑意义 # 效果 优先取出括号内的内容 # 请用正则表达式取图片地址 print(re.findall("src='(.+?)'",src)) # 了解 加上?: 可以取消括号中的优先级 print(re.findall("src='(?:.+?)'",src)) print(re.findall("src='(?:www).(?:baidupic)",src)) print(re.findall('d',src))
15、import subprocess
1 #用来与系统cmd的交互 2 3 #1.从管道中读取数据,管道就是两个进程通讯的媒介 4 res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 5 6 print(type(res.stdout.read().decode("GBK"))) 7 8 #stdout输出管道 9 print(res.stdout.read().decode("GBK")) 10 11 dir = r'dir D:上海python全栈4期day23' 12 find = 'findstr "py"' 13 14 res1 = subprocess.Popen(dir,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 15 #stdin输入管道 16 res2 = subprocess.Popen(find,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=res1.stdout) 17 18 print(res1.stdout.read().decode("GBK")) 19 #stderr错误管道 20 print(res2.stderr.read().decode("GBK"),"33333") 21 22 #总结subpreocess主要用于执行系统指令(启动子进程)与os.system的不同在于,subprocess可以与这个字进程进行数据交换