前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python23 内置模块讲解

Python23 内置模块讲解

作者头像
py3study
发布2020-01-09 16:20:57
1.3K0
发布2020-01-09 16:20:57
举报
文章被收录于专栏:python3python3

模块的分类

参考博客http://www.cnblogs.com/alex3714/articles/5161349.html

python中的模块分为三大类:

代码语言:javascript
复制
1.标准库(内置模块)

2.开源模块(第三方模块)

3.自定义模块(自己写的.py文件模块)

标准库

1.time

UTC是世界标准时间,中国是在东8区(GMT+8)

image_1c0bi1c1j1pkr1rn91ovspjf1omo9.png-4.6kB
image_1c0bi1c1j1pkr1rn91ovspjf1omo9.png-4.6kB

导入time模块,通过time.timezone查看时区,28800是秒单位,除60是分钟,在除60的结果是小时,也就是说中国时区比UTC早8个小时。

1.1 time.time

image_1c0bi20qd1hi61lm35m416qd5e7m.png-2.3kB
image_1c0bi20qd1hi61lm35m416qd5e7m.png-2.3kB

time.time()查看时间戳,以秒为单位,这个数字实际没什么大的意义,只不过是从1970年开始算起到当前经历了多少秒。从1970年开始算是因为这是Unix诞生的时间。

image_1c0bi2huj107sqhj1vej9ifle713.png-5.9kB
image_1c0bi2huj107sqhj1vej9ifle713.png-5.9kB

1507535507/60/60/24/365(最终求的是多少年),结果是从1970年到现在为47年,1970+47就是今年的2017年。

1.2 time.sleep

image_1c0bi30g51bnvevd1391asr7ug1g.png-1.6kB
image_1c0bi30g51bnvevd1391asr7ug1g.png-1.6kB

用于延迟,图中定义了延迟3秒 在写代码时,可以利用time.sleep延迟多久后在继续执行后续的代码。

1.3 time.gmtime

image_1c0bi3mtd4ki1rgt12fvhoka4e1t.png-6.7kB
image_1c0bi3mtd4ki1rgt12fvhoka4e1t.png-6.7kB

以元组的方式转换时间戳,显示转换的时间,默认显示的是当前UTC的时间(不是中国东八区时间),比东八区差了8个小时。

时间格式为:年、月、日、小时、分钟、秒、本周第几天(从0开始算)、本年第几天(1-366)、是否是夏令时

image_1c0bi434g1v2n1aprg9kqrk1te72a.png-7.6kB
image_1c0bi434g1v2n1aprg9kqrk1te72a.png-7.6kB

在括号中输入以秒为单位的数字进行计算UTC的时间(从1970年开始算)

1.4 time.localtime

image_1c0bi5qjai2j1ken227chthjt3h.png-6.6kB
image_1c0bi5qjai2j1ken227chthjt3h.png-6.6kB

以元组的方式转换时间戳,显示的是本地的时间。

image_1c0bi688v11i51g2c1l051srqupe3u.png-10kB
image_1c0bi688v11i51g2c1l051srqupe3u.png-10kB

元组中的时间数据类似字典,当想要取出时间时,取对应的key就可以看到相应的value

image_1c0bi6hjnh7a1v11ut31ul1gmm4b.png-14.9kB
image_1c0bi6hjnh7a1v11ut31ul1gmm4b.png-14.9kB

. 取出指定时间戳,显示是哪年的第多少天。

1.5 time.mktime

image_1c0bi7328c3qj6n8h69bo1snk4o.png-2.7kB
image_1c0bi7328c3qj6n8h69bo1snk4o.png-2.7kB

将具体的格式时间转换为时间戳

1.6 time.strftime与time.strptime

time.strftime用于将具体格式时间转换为格式化的字符串时间

image_1c0bi7ig9t5f9pp144o1f0p5nj55.png-63.7kB
image_1c0bi7ig9t5f9pp144o1f0p5nj55.png-63.7kB

通过help查看用法,可以看到%符号后面对应字母所代表的内容,图中红线部分是使用格式。

image_1c0bi7vd21ov0uisg5714rc1shg5i.png-4.6kB
image_1c0bi7vd21ov0uisg5714rc1shg5i.png-4.6kB

%Y:年 %m:月 %d:日 %H:小时 %M:分钟 %S:秒

image_1c0bi8ktmssm1r8jtj4u1hasv5v.png-61kB
image_1c0bi8ktmssm1r8jtj4u1hasv5v.png-61kB

strptime的使用格式 strptime是用来将字符串转为具体的格式时间

image_1c0bi9cgi81eu0q1g05hsubln6c.png-10.4kB
image_1c0bi9cgi81eu0q1g05hsubln6c.png-10.4kB

strptime是与strftime相反的功能,这里用逗号隔开的两边内容格式要一 一对应,2017对应%Y,10对应%m,这里位置上的联系一定要对应。

image_1c0bi9udvbi1l0ikkf1jea1fs16p.png-9.6kB
image_1c0bi9udvbi1l0ikkf1jea1fs16p.png-9.6kB

strftime使用时间格式默认就是本地时间,可以通过指定其他的时间来输出字符串格式的时间,time.localtime相当于给这个格式赋值

image_1c0bia92f9cg17kj19fchbliiq76.png-13kB
image_1c0bia92f9cg17kj19fchbliiq76.png-13kB

调整格式的位置,输出的字符串时间格式也会随着改变 当前的x相当于2017-10-11 xx:xx:xx,而格式没有与该时间想对应,说明使用strftime在位置上的格式是没有联系的

1.7 time.asctime

image_1c0bianj0dedhi214cm1r1lqq17j.png-19.3kB
image_1c0bianj0dedhi214cm1r1lqq17j.png-19.3kB
image_1c0bias9n1l9974h9njdi6106a80.png-3.5kB
image_1c0bias9n1l9974h9njdi6106a80.png-3.5kB

用英文的方式进行表示(将元组的格式事件转换为英文时间格式)

image_1c0bib8gnbuv17er2dji2oa3r8d.png-3.7kB
image_1c0bib8gnbuv17er2dji2oa3r8d.png-3.7kB

1.8 time.ctime

用于将时间戳转换为英文时间格式

image_1c0bibknfqd91ojs17671eh1k7f8q.png-9.8kB
image_1c0bibknfqd91ojs17671eh1k7f8q.png-9.8kB

2.datetime

datetime.date 获取年月日 datetime.time 获取时分秒 datetime.datetime 获取年月日时分秒

image_1c0bici7tr8jotq6is15nn1def97.png-4.6kB
image_1c0bici7tr8jotq6is15nn1def97.png-4.6kB

获取现在的时间

image_1c0bics6ehj5567qn0cfn7s99k.png-9.6kB
image_1c0bics6ehj5567qn0cfn7s99k.png-9.6kB

显示根据当前时间+3天;显示根据当前时间-3天

image_1c0bidam5djm1mh0125r7irm95a1.png-10.7kB
image_1c0bidam5djm1mh0125r7irm95a1.png-10.7kB

前后的小时 时间


3.random模块

3.1 random.random

Python23 内置模块讲解
Python23 内置模块讲解

随机获取浮点数

3.2 random.randint

image_1c0bieb2um9uquv1cmc1vu2q7qar.png-12.5kB
image_1c0bieb2um9uquv1cmc1vu2q7qar.png-12.5kB

随机获取指定的整数

3.3 random.randrange

image_1c0bien86ad11rh9021n8scnb8.png-13.5kB
image_1c0bien86ad11rh9021n8scnb8.png-13.5kB

使用randrange和range类似,最后一个数字不算

3.4 random.choice

image_1c0bif49i1g9goma1ovhe9912kbl.png-20.2kB
image_1c0bif49i1g9goma1ovhe9912kbl.png-20.2kB

在不同的数据类型中随机选值

3.5 radom.sample

image_1c0big5tn14abk9j1vf2fv01u0oc2.png-14.2kB
image_1c0big5tn14abk9j1vf2fv01u0oc2.png-14.2kB

随机取两个值

3.6 random.uniform random.random默认只能取值0-1的浮点数,可以通过random.uniform来指定浮点数范围

image_1c0bigmvoepf10roneo11nq1etacf.png-20.1kB
image_1c0bigmvoepf10roneo11nq1etacf.png-20.1kB

3.7 random.shuffle(洗×××功能)

image_1c0bihqs5131lh910gk1nfgpqmcs.png-5kB
image_1c0bihqs5131lh910gk1nfgpqmcs.png-5kB

把顺序打乱

3.8 验证码练习 3.8.1使用数字验证

代码语言:javascript
复制
import random

checkcode = ''
for i in range(4):    #指定4位验证码的长度
    current = random.randint(0,9)    #指定随机数字
    checkcode+=str(current)    #将随机的数字加入到变量中
print (checkcode)    #打印随机的验证码
image_1c0bijapt16v2ej91ug01gju14aod9.png-0.7kB
image_1c0bijapt16v2ej91ug01gju14aod9.png-0.7kB

3.8.2使用数字+字母验证

image_1c0bijkuqskr17tshu3036lodm.png-2.6kB
image_1c0bijkuqskr17tshu3036lodm.png-2.6kB

chr65到69 一 一对应了A-Z字母

代码语言:javascript
复制
checkcode = ''
for i in range(4):    #循环4次,相当于4位长度的验证码
    current = random.randint(0,4)    #设定current随机数字与range范围相等
    if current == i:        
        tmp = chr(random.randint(65,90)) #随机匹配:当current等于i时,就随机一个字母
    else:
        tmp=random.randint(0,9)    #当current不等于i时,就随机一个数字
    checkcode+=str(tmp)    #将tmp产生的数字或字母加入到checkcodee变量中
print (checkcode)
image_1c0bikp1po7q13hh1o191t994dne3.png-0.8kB
image_1c0bikp1po7q13hh1o191t994dne3.png-0.8kB

字母+数字的随机验证码


4.OS模块

http://python.usyiyi.cn/translate/python_278/library/os.html os模块使用参考网址

os用于调取系统命令

4.1 os.getcwd

image_1c0bilu6c1cgiu351k6h7dra9eg.png-5.2kB
image_1c0bilu6c1cgiu351k6h7dra9eg.png-5.2kB

获取当前操作目录

4.2 os.chdir

image_1c0bimdeb1d2s1j2t1dg21u8k1tonet.png-4.4kB
image_1c0bimdeb1d2s1j2t1dg21u8k1tonet.png-4.4kB

切换操作目录 c:后面是两个\,第一个\是转译符,使用\只能转译后面的一个符号

image_1c0bin1jl1hmpcaf571vqipunfa.png-7.7kB
image_1c0bin1jl1hmpcaf571vqipunfa.png-7.7kB

通过用r来转义

4.3 os.curdir

image_1c0binjejnbenno1e231nqnek1fn.png-1.5kB
image_1c0binjejnbenno1e231nqnek1fn.png-1.5kB

返回当前目录

一个点'.'表示当前目录

4.4 os.pardir

image_1c0bip3fam0a1pu819kl1m1npf3g4.png-1.5kB
image_1c0bip3fam0a1pu819kl1m1npf3g4.png-1.5kB

返回上级目录

两个'..' 两个点表示上级目录

4.5 os.makedirs与 os.removedirs 4.5.1

image_1c0bipq7lc3d1brj1olr18c1cc8gh.png-2.9kB
image_1c0bipq7lc3d1brj1olr18c1cc8gh.png-2.9kB

在D盘先建立a目录,在a目录中建立b目录,以此类推

image_1c0biq44ifjr1ffe1v2oqt8h1gu.png-7.9kB
image_1c0biq44ifjr1ffe1v2oqt8h1gu.png-7.9kB

makedirs可以建立多个目录

4.5.2

image_1c0bisl0f1v4p1o1sjdk1m881j9thr.png-6.5kB
image_1c0bisl0f1v4p1o1sjdk1m881j9thr.png-6.5kB

在a目录中建立一个文档

image_1c0bitgst1aav7121lt2ge71q6kil.png-2.7kB
image_1c0bitgst1aav7121lt2ge71q6kil.png-2.7kB
image_1c0bitle91v3i73g7ckdbafgtj2.png-5.7kB
image_1c0bitle91v3i73g7ckdbafgtj2.png-5.7kB

可以看到除了D盘和a目录,其他目录都被删除了;这是因为使用os.removedirs是删除空的目录,当前D盘和a目录都是非空

removedirs是递归的删除,只要上一层目录为空就删除,会删掉多个空的目录

4.6 os.mkdir mkdir也是用于建立目录的,只不过是建立单个目录的

image_1c0bj1gu11a331ou15teheq1r4tjf.png-11.1kB
image_1c0bj1gu11a331ou15teheq1r4tjf.png-11.1kB

建立多个目录失败

image_1c0bj1r2mditgbv1rc63063vdjs.png-2.3kB
image_1c0bj1r2mditgbv1rc63063vdjs.png-2.3kB
image_1c0bj1vtteng7qrqqgire16m9k9.png-6.5kB
image_1c0bj1vtteng7qrqqgire16m9k9.png-6.5kB

建立单个目录,建立多级目录的话,需要一个一个的去建立

4.7 os.rmdir

image_1c0bj2iv61dfc2u57lj9h75pkkm.png-3.5kB
image_1c0bj2iv61dfc2u57lj9h75pkkm.png-3.5kB

将原有的目录删除,重新建立,然后通过rmdir删除,只会删除一个目录,不会删除多个。

image_1c0bj49811nkr9f41n9l1msvmsrmg.png-4.7kB
image_1c0bj49811nkr9f41n9l1msvmsrmg.png-4.7kB

4.8 os.listdir

image_1c0bj431l1tdrdrsn3nmd4afm3.png-10.8kB
image_1c0bj431l1tdrdrsn3nmd4afm3.png-10.8kB

以列表的方式列出当前目录有哪些内容

‘.’表示当前目录

默认也是列出当前目录

image_1c0bj4oat1ff79bj1fd81fnavp6mt.png-2.6kB
image_1c0bj4oat1ff79bj1fd81fnavp6mt.png-2.6kB

列出指定目录内容

4.9 os.remove 删除指定内容

4.10 os.rename os.rename('oldname','newname') 重命名

4.11 os.stat 获取指定内容属性信息

image_1c0bj5ht865hct4ldhhi216itna.png-9kB
image_1c0bj5ht865hct4ldhhi216itna.png-9kB

4.12 os.sep

在Windows中路径是用 右斜杠\ 来表示分隔的

在linux中路径是用左斜杠/来表示分隔

image_1c0bj5sd11s1o38b1nmg1pr3i4nn.png-18.6kB
image_1c0bj5sd11s1o38b1nmg1pr3i4nn.png-18.6kB

os.sep会根据系统的不同,来改变分隔符的,在Windows中是\(其中一个\是转译符),使用os.sep代替\,这样即使在不同的操作系统也能正确的使用对应的分隔符

4.13 os.linesep

image_1c0bj67giohb36b71s13ad1j6po4.png-1.7kB
image_1c0bj67giohb36b71s13ad1j6po4.png-1.7kB

换行符是\r\n

4.14 os.environ与os.pathsep

image_1c0bj6ivthkr1io7106r1fj2vtoh.png-71.6kB
image_1c0bj6ivthkr1io7106r1fj2vtoh.png-71.6kB

通过environ获取系统的环境变量,以字典格式显示,在Windows中 如果一个key对应多个路径的话是以分好‘;’分隔的,os.pathsep就是对应这个分隔符(在Windows中对应‘;’,在linux中对应‘:’)

image_1c0bj6uhrr4vhhh1b7fjf15a5ou.png-1.8kB
image_1c0bj6uhrr4vhhh1b7fjf15a5ou.png-1.8kB

4.15 os.name

image_1c0bj8q52kj31hgh7j6aii18sopb.png-1.5kB
image_1c0bj8q52kj31hgh7j6aii18sopb.png-1.5kB

显示当前系统类型,nt表示Windows

4.16 os.system

用来执行当前系统的命令

image_1c0bj96gs7pf19q535813hk1720po.png-44.2kB
image_1c0bj96gs7pf19q535813hk1720po.png-44.2kB

编码不同,所以显示乱码

4.17 os.path

4.17.1 os.path.abspath 获取绝对路径(之前在导入模块时使用过,导入不同目录的模块)

4.17.2 os.path.split

image_1c0bjac20lmcubf17sj1p4hjl2q5.png-4.2kB
image_1c0bjac20lmcubf17sj1p4hjl2q5.png-4.2kB

以元组的方式显示,将目录和文件分隔开。

4.17.3 os.path.dirname与os.path.basename

image_1c0bjaqd1aaplif1eqh7q1unkqi.png-10kB
image_1c0bjaqd1aaplif1eqh7q1unkqi.png-10kB

一个取目录名,一个结尾的。

4.17.4 os.path.exist

image_1c0bjbbhm1rp1g5b1ja31n811eqjqv.png-2.6kB
image_1c0bjbbhm1rp1g5b1ja31n811eqjqv.png-2.6kB

判断路径是否存在

4.17.5 os.path.isabs

image_1c0bjce57l1b27a1ptj1ieatnors.png-2.8kB
image_1c0bjce57l1b27a1ptj1ieatnors.png-2.8kB

判断是否是以根开头的绝对路径 在Windows中每个盘符都是根,在linux中/是根 如果False的话就是相对路径

4.17.6 os.path.isfile与 os.path.isdir

image_1c0bjet2f14qbkr416vb17io12p2s9.png-5.7kB
image_1c0bjet2f14qbkr416vb17io12p2s9.png-5.7kB

判断是否是一个文件

image_1c0bjf7g71tr21746s0h1u2t12pnsm.png-2.8kB
image_1c0bjf7g71tr21746s0h1u2t12pnsm.png-2.8kB

判断是否是目录

4.17.7 os.path.join

image_1c0bjgf4j1q7eu04c1r1v2uu0lt3.png-4.3kB
image_1c0bjgf4j1q7eu04c1r1v2uu0lt3.png-4.3kB

将目录与文件组合并返回

4.17.8 os.path.getatime与 os.path.getmtime

image_1c0bjguheji37n6g2r1m07594tg.png-6.9kB
image_1c0bjguheji37n6g2r1m07594tg.png-6.9kB

获取文件的最后存取时间,时间格式为时间戳

image_1c0bjha236ln1ckt1ups1kqoqqstt.png-6.9kB
image_1c0bjha236ln1ckt1ups1kqoqqstt.png-6.9kB

获取修改时间


5. sys与shutil模块

sys模块没有细讲,请单独翻阅资料 5.1 sys.version

image_1c0bji91j1kg81f69154j10s71nagua.png-8.1kB
image_1c0bji91j1kg81f69154j10s71nagua.png-8.1kB

获取当前python的版本信息

5.2 sys.argv 获取相对路径(初始模块文章中讲过)


6. shutil模块

shutil用于copy文件用的

6.1 shutil.copyfileobj

代码语言:javascript
复制
import shutil

f1 = open('test1.txt',encoding='utf-8')

f2 = open('test2.txt','w',encoding='utf-8')

shutil.copyfileobj(f1,f2)
image_1c0bjmetm1v2eg3m10kbsf4qv2v7.png-6.8kB
image_1c0bjmetm1v2eg3m10kbsf4qv2v7.png-6.8kB

成功的将test1中的内容copy到test2

6.2 shutil.copyfile

shutil.copyfile中已经带有打开文件的代码,所以无需额外再次打开文件了,直接使用即可

image_1c0bjn1en19mb1dtg10fh1rgm1et1vk.png-4.4kB
image_1c0bjn1en19mb1dtg10fh1rgm1et1vk.png-4.4kB
image_1c0bjn7at9mg1hkm1aceb0k15pt101.png-7.3kB
image_1c0bjn7at9mg1hkm1aceb0k15pt101.png-7.3kB

6.3 shutil.copymode 将文件的权限拷贝,新文件的用户属主是新用户

6.4 shutil.copystat

image_1c0bjnjkf57o1nu2vce14jitl10e.png-4.1kB
image_1c0bjnjkf57o1nu2vce14jitl10e.png-4.1kB

只copy了权限

6.5 shutil.copytree与shutil.rmtree

image_1c0bjo3dgsa21lqq12i21bsq1v5210r.png-19.2kB
image_1c0bjo3dgsa21lqq12i21bsq1v5210r.png-19.2kB
image_1c0bjo8tr1t61v3ni3o5ee1hjj118.png-20.4kB
image_1c0bjo8tr1t61v3ni3o5ee1hjj118.png-20.4kB

6.6 shutil.make_arvhive

image_1c0bjoiqr1fgcc48flo15mo1sgg11l.png-3.5kB
image_1c0bjoiqr1fgcc48flo15mo1sgg11l.png-3.5kB
image_1c0bjp4qm1dkr1qfks8kjnl2j2122.png-19.9kB
image_1c0bjp4qm1dkr1qfks8kjnl2j2122.png-19.9kB

默认在当前操作目录

image_1c0bjpfd5asvrjb1j8joh188h12f.png-6.8kB
image_1c0bjpfd5asvrjb1j8joh188h12f.png-6.8kB
image_1c0bjpmb812ja17m31buts8hqtg12s.png-2.1kB
image_1c0bjpmb812ja17m31buts8hqtg12s.png-2.1kB

指定目录

6.7 zipfile、tarfile

代码语言:javascript
复制
import zipfile

压缩

代码语言:javascript
复制
z = zipfile.ZipFile('laxi.zip', 'w')

z.write('a.log')

z.write('data.data')

z.close()

解压

代码语言:javascript
复制
z = zipfile.ZipFile('laxi.zip', 'r')

z.extractall()

z.close() 

压缩

代码语言:javascript
复制
import tarfile

tar = tarfile.open('your.tar','w')

tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')

tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')

tar.close()

解压

代码语言:javascript
复制
tar = tarfile.open('your.tar','r')

tar.extractall()  # 可设置解压地址

tar.close() 

7. json、pickle、shelve

json,用于字符串 和 python数据类型间进行转换

pickle,用于python特有的类型 和 python的数据类型间进行转换

Json模块提供了四个功能:dumps、dump、loads、load

pickle模块提供了四个功能:dumps、dump、loads、load

7.1 json

json之前整理过,可以在不同的语言或系统平台进行数据的转换

只支持部分数据类型

代码语言:javascript
复制
s1={"k1":"v1"}

st=json.dumps(s1)

print(st,type(st))

s='{"k1":"v1"}'

dic=json.loads(s)

print(dic,type(dic)) 
代码语言:javascript
复制
输出结果为:

{"k1": "v1"} <class 'str'>

{'k1': 'v1'} <class 'dict'> 

可以看出json的dumps方法处理数据时会将数据转换为字符类型,loads则会重新还原它的类型。

再来看json的dump和load方法,通过示例来了解:

代码语言:javascript
复制
li=[11,22,33]

li=json.dump(li,open('db','w'))

li=json.load(open('db','r'))

print(li,type(li)) 
代码语言:javascript
复制
输出结果为:

[11, 22, 33] <class 'list'>

Json模块dumps、loads、load、dump的区别:

load,dump可加载外部文件,处理文件的数据,dumps,loads主要处理内存中的数据

7.2 pickle

pickle之前整理过,只能在python之间数据进行转换(如不同版本)

支持全部数据类型

代码语言:javascript
复制
import pickle

i=[11,22,33]

r=pickle.dumps(li)

print(r)

result=pickle.loads(r)

print(result) 
代码语言:javascript
复制
 结果为:

b'\x80\x03]q\x00(K\x0bK\x16K!e.'

[11, 22, 33] 

pickle的dupms方法会将数据存为pickle特有的数据类型 

再看pickle的dump和load方法,通过示例我们来了解:

代码语言:javascript
复制
import pickle

i=[11,22,33]

pickle.dump(i,open('db','wb'))

result=pickle.load(open('db','rb'))

print(result) 
代码语言:javascript
复制
    结果为:

[11, 22, 33]

需要注意的是dump文件或者load文件是需要使用二进制。

7.3 shelve

shelve是一额简单的数据存储方案,他只有一个函数就是open(),这个函数接收一个参数就是文件名,然后返回一个shelf对象,你可以用他来存储东西,就可以简单的把他当作一个字典,当你存储完毕的时候,就调用close函数来关闭。

代码语言:javascript
复制
f = shelve.open('user.db','wc')

f['baidu'] = 'www.baidu.com'

f['qq'] = 'www.qq.com'

f['360'] = 'www.360.cn'

f.close()

f = shelve.open('user.db','a+')

print(f['baidu'],f['qq'],f['360']) 
代码语言:javascript
复制
结果为:

www.baidu.com

www.qq.com

www.360.cn 

对shelve序列化数据进行更新操作,通过示例来进行学习:

代码语言:javascript
复制
f=shelve.open('user_db','c')

f["user"]={"数码电器": {"打印机": "3600", "手机": "3800", "电脑": "8000", "照相机": "10000"},

     "服装百货": {"方便面": "4", "夹克": "300", "牛仔裤": "288", "王老吉": "6"},

     "化妆品": {"韩束": "388", "欧诗漫": "666", "欧莱雅": "888", "百雀羚": "259"},

     "汽车":{"帕沙特": "250000", "奇瑞": "100000", "特斯拉": "999999", "宝马X5": "550000"}

     }

a=(f["user"])

a.update({"食品":{"猪肉":"12","牛肉":"28","鸡肉":"8","羊肉":"32",}})

f["user"]=a

f.close()

f=shelve.open('user_db','a')

print(f["user"]) 

8. xml处理模块

xml与json类似,json使用起来更简单,只不过在json没有诞生时,使用的就是xml。

不过现在有一些企业依然使用xml来取xml数据

xml是通过<>节点来区别数据结构的

8.1 xml处理

image_1c0bk16o75am1kb91dnr1gf31mie139.png-92.8kB
image_1c0bk16o75am1kb91dnr1gf31mie139.png-92.8kB

这是一个xml文件的内容

代码语言:javascript
复制
import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")  #要处理xmltest.xml文件
root = tree.getroot()
print(root)     #只会打印出内存地址
print(root.tag)   #会打印出内存地址对应的内容
image_1c0bk1qviaeq1giv12il1ovu1lsv13m.png-3.2kB
image_1c0bk1qviaeq1giv12il1ovu1lsv13m.png-3.2kB

将第一行的data给打印出来了

代码语言:javascript
复制
遍历xml文档
for child in root:
    print(child.tag, child.attrib)  

    for i in child:
        print(i.tag, i.text,i.attrib)
image_1c0bk2ruq11a21014kkf1dli12cv143.png-31.6kB
image_1c0bk2ruq11a21014kkf1dli12cv143.png-31.6kB
image_1c0bk31imjaqi9k20enh8pr714g.png-14.7kB
image_1c0bk31imjaqi9k20enh8pr714g.png-14.7kB

child.tag是xml文件中的标签名(如:country), child.attrib是属性(如:name="Liechtenstein")

image_1c0bk3g9sssm1v2l4601tvb50314t.png-3.2kB
image_1c0bk3g9sssm1v2l4601tvb50314t.png-3.2kB
代码语言:javascript
复制
i.tag表示rank(标签名)

i.text表示2 (值)

i.attrib表示updated="yes"> (属性)
代码语言:javascript
复制
只遍历year 节点
for node in root.iter('year'):
    print(node.tag, node.text)
image_1c0bk4kh21kev18nh8qa1m8d8do15q.png-1.7kB
image_1c0bk4kh21kev18nh8qa1m8d8do15q.png-1.7kB

8.2 xml修改

代码语言:javascript
复制
import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")
root = tree.getroot()

for node in root.iter('year'):                #循环year有关的节点
    new_year = int(node.text) + 1        #循环的是字符串,需要转换成数字然后+1(加一年)
    node.text = str(new_year)               #text表示值,将这个值(20XX)转换为字符串
    node.set("updated_by", "Alex")        #新增属性

tree.write("xmltest.xml")                    #将内容写入源文件(xmltest.xml)
image_1c0bk53bv1kkcic2mu8ukm412167.png-60.9kB
image_1c0bk53bv1kkcic2mu8ukm412167.png-60.9kB

可以看到源文件中的year值都加了一年

8.3 删除

image_1c0bk5omclpk1gdo1qrq1h5lf16k.png-37.1kB
image_1c0bk5omclpk1gdo1qrq1h5lf16k.png-37.1kB

删除之前有一个叫Panama的country

代码语言:javascript
复制
for country in root.findall('country'):     #查找所有country
    rank = int(country.find('rank').text)   #查找country下面的rank
    if rank > 50:                           #如果ran中的值大于50就删除当前country
        root.remove(country)

tree.write('output.xml')
image_1c0bk67dp15ah11031umb1bvo1tvs171.png-59.1kB
image_1c0bk67dp15ah11031umb1bvo1tvs171.png-59.1kB

已经看不到Panama这个country了

8.4 创建

代码语言:javascript
复制
import xml.etree.ElementTree as ET

new_xml = ET.Element("personinfolist")  #根节点personinfolist
personinfo = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "yes"}) #创建new_xml的子节点; personinfo是节点名;attrib是属性

name = ET.SubElement(personinfo, "name")    #该节点是personinfo的子节点
name.text = "Alex Li"
age = ET.SubElement(personinfo, "age", attrib={"checked": "no"})
sex = ET.SubElement(personinfo, "sex")
age.text = '56'
personinfo2 = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "no"})
name = ET.SubElement(personinfo2, "name")
name.text = "Oldboy Ran"
age = ET.SubElement(personinfo2, "age")
age.text = '19'

et = ET.ElementTree(new_xml)  # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True) #xml_declaration表示生成的格式是xml

ET.dump(new_xml)  # 打印生成的格式
image_1c0bk9b29q2j1fvqi51jtqep818r.png-23.8kB
image_1c0bk9b29q2j1fvqi51jtqep818r.png-23.8kB

可以看到生成的xml文件,只不过默认格式不对,需要手动调整一下。

image_1c0bk91cmoa41peh4g1n8p7aj18e.png-34.4kB
image_1c0bk91cmoa41peh4g1n8p7aj18e.png-34.4kB

调整后的文件


9. PyYAML和configparser

9.1 PyYAML

PyYAML是用来做配置文件的

9.2 configparser

configparser 可以用来生成和修改常见配置文件,如:以conf为结尾的配置文件

python3的写法:configparser

python2的写法:ConfigParser

9.2.1 写入

代码语言:javascript
复制
import configparser

config = configparser.ConfigParser()    #生成处理对象并赋值

config['DEFAULT']={'ServerAliveInterval':'45',
'Compression':'yes',
'CompressionLevel':'9',
'ForwardX11':'yes'}

config["DEFAULT"] = {'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9'}   #生成配置文件内容,以字典的方式

config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'      #与上面的结果一样,只是写的方式不同

config['topsecret.server.com'] = {}
config['topsecret.server.com']
config['topsecret.server.com']['Host Port'] = '50022'  # mutates the parser
config['topsecret.server.com']['ForwardX11'] = 'no'  # same here

config['DEFAULT']['ForwardX11'] = 'yes'

with open('example.ini', 'w') as configfile:
    config.write(configfile)
image_1c0bkari3boj1m7n1k8k1k5l1ato198.png-22.3kB
image_1c0bkari3boj1m7n1k8k1k5l1ato198.png-22.3kB

通过python生成的一个配置文件

红色表示节点,图中内容有三个节点

9.2.2 读取

代码语言:javascript
复制
import configparser

conf = configparser.ConfigParser()
conf.read("example.ini")

print(conf.defaults())    
image_1c0bkc815nst6m1e661a9oe741a5.png-4.8kB
image_1c0bkc815nst6m1e661a9oe741a5.png-4.8kB

使用defaults可以调用example.ini文件中的[DEFAULT]对应的内容,defaults是自带的操作方法

代码语言:javascript
复制
print(conf['bitbucket.org']['user'])
image_1c0bkcl3mqjm76t1shv17rfp641ai.png-0.5kB
image_1c0bkcl3mqjm76t1shv17rfp641ai.png-0.5kB

其他的节点只能通过字典的方式来调用

代码语言:javascript
复制
sec = conf.remove_section('bitbucket.org')    #删除指定节点
conf.write(open('example.ini', "w"))    #写入
image_1c0bkd6vlfq01pebk4v18vnmlt1av.png-14.1kB
image_1c0bkd6vlfq01pebk4v18vnmlt1av.png-14.1kB

10. hashlib

用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

10.1 MD5

代码语言:javascript
复制
import hashlib

m = hashlib.md5()        #使用MD5算法
m.update(b'Hello')        #b表示bytes类型
print (m.hexdigest())    #使用十六进制打印,hexdigest就表示十六进制格式
m.update(b'Its me')
print (m.hexdigest())
image_1c0bkds20b5pcj516111e3o10uo1bc.png-4kB
image_1c0bkds20b5pcj516111e3o10uo1bc.png-4kB

第一个生成的MD5是Hello

第二个生成的MD5是Hello加上Its me

因为MD5值不能翻转,所以通过其他方式确认第二个MD5是否是两个字符串加在一起生成的

image_1c0bke7bg1u7r1r6t1fv21hlj1jh11bp.png-20.3kB
image_1c0bke7bg1u7r1r6t1fv21hlj1jh11bp.png-20.3kB
image_1c0bkepk356oc721kmo1di115it1c6.png-4.7kB
image_1c0bkepk356oc721kmo1di115it1c6.png-4.7kB

可以看到通过m2打印的MD5 值与之前的一样,说明之前的解释没有错。

10.2 sha

代码语言:javascript
复制
m3 = hashlib.sha3_512()
m3.update(b'HelloIts me')
print (m3.hexdigest())
image_1c0bkfkun1anc10kljrq19io1pgq1cj.png-15.2kB
image_1c0bkfkun1anc10kljrq19io1pgq1cj.png-15.2kB

sha512加密长度深,算法复杂度也高,但效率也是相对较低

10.3 hmac

python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密

散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;

一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。

代码语言:javascript
复制
import hmac
h = hmac.new(b'12345',b'qwerasdf')   #abc123是key,1234qwer是消息,
print (h.hexdigest())
image_1c0bkg34d1psdvb7ivm2hk1bpt1d0.png-2.8kB
image_1c0bkg34d1psdvb7ivm2hk1bpt1d0.png-2.8kB
image_1c0bkg9efd92t111umb1asp79b1dd.png-13.3kB
image_1c0bkg9efd92t111umb1asp79b1dd.png-13.3kB
image_1c0bkgeo816sl1hp2jenspbkv41dq.png-13.5kB
image_1c0bkgeo816sl1hp2jenspbkv41dq.png-13.5kB

默认不能用中文,只能用ASCII码(前面有b,必须生成bytes格式,bytes格式要用ASCII)

image_1c0bkgsljgjv127ntjd1lk3pac1e7.png-11.9kB
image_1c0bkgsljgjv127ntjd1lk3pac1e7.png-11.9kB

key必须使用bytes格式,消息可以使用中文,但需要将前面的b去掉,然后并封装新的格式(utf-8)

image_1c0bkh7i3t251lccs4i11bsohv1ek.png-2.8kB
image_1c0bkh7i3t251lccs4i11bsohv1ek.png-2.8kB

11. subprodcess

subprodcess是os.system和os.spawn的替代模块 subprocess是Python 2.4中新增的一个模块,它允许你生成新的进程,连接到它们的 input/output/error 管道,并获取它们的返回(状态)码。这个模块的目的在于替换几个旧的模块和方法,如os.system、os.spawn、os.popen、commands.等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

常用方法:

subprocess.call():执行命令,并返回执行状态,其中shell参数为False时,命令需要通过列表的方式传入,当shell为True时,可直接传入命令

(1) 示例如下:

代码语言:javascript
复制
import subprocess
a = subprocess.call(['df','-hT'],shell=False)
print(a)

执行结果:
文件系统                类型      容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root xfs        22G  9.0G   14G   41% /
devtmpfs                devtmpfs  894M     0  894M    0% /dev
tmpfs                   tmpfs     910M     0  910M    0% /dev/shm
tmpfs                   tmpfs     910M   19M  892M    3% /run
tmpfs                   tmpfs     910M     0  910M    0% /sys/fs/cgroup
/dev/sda1               xfs      1014M  233M  782M   23% /boot
tmpfs                   tmpfs     182M  4.0K  182M    1% /run/user/42
tmpfs                   tmpfs     182M   48K  182M    1% /run/user/0
0

(2)

subprocess.check_call():用法与subprocess.call()类似,区别是,当返回值不为0时,直接抛出异常

代码语言:javascript
复制
import subprocess
a = subprocess.check_call('ifconfig',shell=True)
print(a)

执行结果:
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.200.150  netmask 255.255.255.0  broadcast 192.168.200.255
        inet6 fe80::1715:d111:c3d7:a081  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:bd:d1:99  txqueuelen 1000  (Ethernet)
        RX packets 757729  bytes 831629447 (793.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 207676  bytes 58597215 (55.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(3)

代码语言:javascript
复制
import subprocess
a = subprocess.check_call('abcd',shell=True)
print(a)

执行结果:
/bin/sh: abcd: 未找到命令
Traceback (most recent call last):
  File "/tmp/pycharm_project_538/codes_practice/aa1/A4.py", line 2, in <module>
    a = subprocess.check_call('abcd',shell=True)
  File "/usr/local/lib/python3.6/subprocess.py", line 291, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'abcd' returned non-zero exit status 127.

(4) subprocess.check_output():用法与上面两个方法类似,区别是,如果当返回值为0时,直接返回输出结果,如果返回值不为0,直接抛出异常。需要说明的是,该方法在python3.x中才有。

(5) subprocess.Popen():

在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要使用到suprocess的Popen()方法。该方法有以下参数:

args:shell命令,可以是字符串,或者序列类型,如list,tuple。

bufsize:缓冲区大小,可不用关心

stdin,stdout,stderr:分别表示程序的标准输入,标准输出及标准错误

shell:与上面方法中用法相同

cwd:用于设置子进程的当前目录

env:用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量

universal_newlines:不同系统的的换行符不同,当该参数设定为true时,则表示使用\n作为换行符

(5.1)

代码语言:javascript
复制
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write('print(1) \n')
obj.stdin.write('print(2) \n')
obj.stdin.write('print(3) \n')
obj.stdin.close()

cmd_out = obj.stdout.read()
obj.stdout.close()
cmd_error = obj.stderr.read()
obj.stderr.close()

print (cmd_out)
print (cmd_error)

(5.2) Popen.communicate(input=None) 与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。 Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如 果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

使用如下方法:

代码语言:javascript
复制
import subprocess

obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
obj.stdin.write('print(1) \n')
obj.stdin.write('print(2) \n')
obj.stdin.write('print(3) \n')
obj.stdin.close()

out_error_list = obj.communicate()
print (out_error_list)

(5.3) 将一个子进程的输出,作为另一个子进程的输入:

代码语言:javascript
复制
import subprocess
child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.communicate()

(5.4)

代码语言:javascript
复制
import subprocess
child = subprocess.Popen('sleep 60',shell=True,stdout=subprocess.PIPE)
Popen.poll() 
用于检查子进程是否已经结束。设置并返回returncode属性。

Popen.wait() 
等待子进程结束。设置并返回returncode属性。

Popen.communicate(input=None)
与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。 Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如 果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

Popen.send_signal(signal) 
向子进程发送信号。

Popen.terminate()
停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

Popen.kill()
杀死子进程。

Popen.stdin 
如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。

Popen.stdout 
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。

Popen.stderr 
如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回 None。

Popen.pid 
获取子进程的进程ID。

Popen.returncode 
获取进程的返回值。如果进程还没有结束,返回None。

12. logging

12.1 日志级别信息输出

代码语言:javascript
复制
import logging

logging.debug('test debug')
logging.info('test info')

logging.warning('the warning info')
logging.error('the error info')
logging.critical('the critical info')
image_1c0bki7b07ro17qo1ln5pl91l1a1f1.png-5.9kB
image_1c0bki7b07ro17qo1ln5pl91l1a1f1.png-5.9kB
代码语言:javascript
复制
logging.basicConfig(filename='app.log',level=logging.DEBUG)   

这条代码一定要放在下面代码的上面才会生效。 这里日志级别是DEBUG,意思就是将DEBUG以及比其高的级别的日志都进行输出

image_1c0bkithj173f3g1up9q1a10p51fe.png-8.7kB
image_1c0bkithj173f3g1up9q1a10p51fe.png-8.7kB

可以看到新增代码后,就不在pycharm中输出日志信息了

image_1c0bkl9qgk8b1ua1aon5jk13791fr.png-28.5kB
image_1c0bkl9qgk8b1ua1aon5jk13791fr.png-28.5kB

根据指定的app.log文件,将信息输出到文件中。

image_1c0bkm4gf19dk1h1c1hncdr0gfq1g8.png-43kB
image_1c0bkm4gf19dk1h1c1hncdr0gfq1g8.png-43kB

在执行一遍代码,日志信息就会增加到app.log文件中(不会覆盖)

image_1c0bkmfto1o8tnj1lm61l1r13jf1gl.png-26kB
image_1c0bkmfto1o8tnj1lm61l1r13jf1gl.png-26kB

将WARNING级别以及比其高的级别日志信息输出

image_1c0bkmpdn1bf7e1m6oc1tkuue21h2.png-12.1kB
image_1c0bkmpdn1bf7e1m6oc1tkuue21h2.png-12.1kB

12.3 添加日志格式

代码语言:javascript
复制
logging.basicConfig(filename='app.log',level=logging.WARNING,format='%(asctime)s %(message)s',datefmt='%m/%d/%Y %I:%M:%S %p')   

format定义日志格式内容; datefmt定义时间格式(月/日/年 时分秒 %p表示上午或下午)

image_1c0bkoe9f138a1na9chb13ar1b761hf.png-15.5kB
image_1c0bkoe9f138a1na9chb13ar1b761hf.png-15.5kB
image_1c0bkrbqa85l1fgp1l1a866sri1k9.png-42.9kB
image_1c0bkrbqa85l1fgp1l1a866sri1k9.png-42.9kB
image_1c0bkr6gptgcde569016kas521js.png-15.7kB
image_1c0bkr6gptgcde569016kas521js.png-15.7kB

定义日志格式,让其显示日志级别

image_1c0bkrjeb1gjsni19bt147i1pvg1km.png-12.4kB
image_1c0bkrjeb1gjsni19bt147i1pvg1km.png-12.4kB
image_1c0bkrqmc12861usn1k81180icta1l3.png-16.4kB
image_1c0bkrqmc12861usn1k81180icta1l3.png-16.4kB

显示输出的文件名

image_1c0bks4ih1o511rvi1ihl1q9mtq31lg.png-28.6kB
image_1c0bks4ih1o511rvi1ihl1q9mtq31lg.png-28.6kB

因为格式原因输出有乱码,实际输出的应该是logging模块.py

image_1c0bkshlk18rvi6n12ea1iq45901lt.png-16.9kB
image_1c0bkshlk18rvi6n12ea1iq45901lt.png-16.9kB

使用%(lineno)d可以显示输出文档的行号

image_1c0bkssbuj2p19hhajt17be2r21ma.png-17.5kB
image_1c0bkssbuj2p19hhajt17be2r21ma.png-17.5kB

可以看到该日志信息是通过哪个文档的哪一行输出的。

image_1c0bkt6lduufgsr1lon3n9maa1mn.png-17kB
image_1c0bkt6lduufgsr1lon3n9maa1mn.png-17kB

%(funcName)s显示生成日志的函数名称

image_1c0bktgim1iodlkj1786umi18us1n4.png-7.8kB
image_1c0bktgim1iodlkj1786umi18us1n4.png-7.8kB
image_1c0bktoukd4sj751dmu18npjqd1nh.png-26.4kB
image_1c0bktoukd4sj751dmu18npjqd1nh.png-26.4kB

可以看到app_run;不是通过函数则为空(<module>)

12.4 logging模块涉及四个主要类

logger提供了应用程序可以直接使用的接口

handler将(logger创建的)日志记录发送到合适的目的输出(输出到屏幕、文件、邮件等);

filter提供了细度设备来决定输出哪条日志记录;

formatter决定日志记录的最终输出格式。

12.4.1 logger logger相当于一个接口,发送日志都需要调用logger。

每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger: LOG=logging.getLogger(”chat.gui”) #返回一个logger对象,如果没有指定name,返回root logger。只要name相同,返回的logger对象都是同一个而且只有一个,即name和logger对象是一一对应的。这意味着,无需把logger对象在各个模块中传递。只要知道name,就能得到同一个logger对象。

通常logger的名字我们对应模块名,如聊天模块、数据库模块、验证模块等。 而核心模块可以这样: LOG=logging.getLogger(”chat.kernel”)

代码语言:javascript
复制
Logger.setLevel(lel): #指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt): #添加或删除指定的filter (这个很少用到)
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr): #增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical(): #可以设置的日志级别

12.4.2 handler

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

代码语言:javascript
复制
Handler.setLevel(lel): #指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter(): #给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt): #新增或删除一个filter对象

每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler: 1) logging.StreamHandler(输出到屏幕) 使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:

代码语言:javascript
复制
    StreamHandler([strm])
    其中strm参数是一个文件对象。默认是sys.stderr

2) logging.FileHandler(输出到文件) 和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:

代码语言:javascript
复制
    FileHandler(filename[,mode])
    filename是文件名,必须指定一个文件名。
    mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。

3) logging.handlers.RotatingFileHandler

这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是: RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]) 其中filename和mode两个参数和FileHandler一样。 maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。 backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。

4) logging.handlers.TimedRotatingFileHandler 这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是: TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]) 其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。 interval是时间间隔。 when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值: S 秒 M 分 H 小时 D 天 W 每星期(interval==0时代表星期一) midnight 每天凌晨

12.4.2.1输出到多个目的

代码语言:javascript
复制
import logging
logger = logging.getLogger('TEST-LOG')  #获取接口对象
logger.setLevel(logging.DEBUG)      #定义记录告警信息的最低等级

ch = logging.StreamHandler()    #定义Handler,可以输出到屏幕
ch.setLevel(logging.WARNING)    #定义输出到屏幕的告警级别

fh = logging.FileHandler('access.log',encoding='utf-8')      #定义Handler输出到信息的文件名称
fh.setLevel(logging.ERROR)      #定义输出到文件的告警级别

ch_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')   #定义Handler输出到屏幕的格式
fh_formatter = logging.Formatter('%(asctime)s - %(process)d  %(filename)s:%(lineno)d')   #定义Handler输出到文件的格式

ch.setFormatter(ch_formatter)   #关联Handler输出到屏幕的格式
fh.setFormatter(fh_formatter)   #关联Handler输出到文件的格式

logger.addHandler(fh)   #增加被输出的内容,与logger接口对象做关联
logger.addHandler(ch)   #增加被输出的内容,与logger接口对象做关联
#屏幕和文件中都可以被输出

logger.warning('aaaa')  #定义告警级别和信息
logger.error('bbbb')    #定义告警级别和信息
image_1c0bl46en1i8g5cad4t13r31f821qb.png-7kB
image_1c0bl46en1i8g5cad4t13r31f821qb.png-7kB

输出到屏幕的告警信息,因为定义的最低告警级别是warning,所以两个级别的信息都可以看到

image_1c0bl4fl5ab7l2u801vloam71qo.png-10.8kB
image_1c0bl4fl5ab7l2u801vloam71qo.png-10.8kB

输出到文件的告警信息,因为定义的级别是error,所以比error低的告警信息warning信息是看不到的

12.4.2.2 按大小自动截断

代码语言:javascript
复制
import logging
from logging import handlers    #需要单独import handlers这个函数

logger = logging.getLogger('TEST')
log_file = "test-log.log"
fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3,encoding='utf-8')
#文件名为log_file,每个文件最大存储10字节,最多保留3个备份文件。

formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.warning("test1")
logger.warning("test2")
logger.warning("test3")
logger.warning("test4")
logger.warning("test5")
logger.warning("test6")
image_1c0bl5cqkr4oshurnh1tr9qgh1r5.png-43.1kB
image_1c0bl5cqkr4oshurnh1tr9qgh1r5.png-43.1kB

可以看到自动截断,只保留了3个备份文件,当前主文件的内容就是最后存储的信息'test6'

image_1c0bl5m6nmvp1stm1mve7du1u151ri.png-12.5kB
image_1c0bl5m6nmvp1stm1mve7du1u151ri.png-12.5kB

log.1是最接近主文件的内容的,所以是'test5'

image_1c0bl638t1274b47u0ov7uihe1rv.png-13kB
image_1c0bl638t1274b47u0ov7uihe1rv.png-13kB

log.3文件存储的是最旧的内容,因为只能每个文件最大10字节,且有3个备份文件的限制,之前的'test1'和'test2'都被删除了。

12.4.2.3 按时间自动截断

代码语言:javascript
复制
fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)

import logging
from logging import handlers    #需要单独import handlers这个函数
import time

logger = logging.getLogger('TEST')
log_file = "test-log.log"

fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3,encoding='utf-8')

#使用handlers.TimedRotatingFileHandler,S表示秒,5就是每隔5秒

formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.warning("test1")
time.sleep(2)
logger.warning("test2")
time.sleep(2)
logger.warning("test3")
logger.warning("test4")
time.sleep(2)
logger.warning("test5")
logger.warning("test6")
image_1c0bl79c51sc5197p10et1bm619ps1sc.png-40.2kB
image_1c0bl79c51sc5197p10et1bm619ps1sc.png-40.2kB

从第5秒开始截断的


13. re正则表达式模块

13.1 函数语法:

代码语言:javascript
复制
re.match(pattern,string, flags=0) 

匹配成功re.match方法返回一个匹配的对象,否则返回None。

我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

13.2 re.match函数

函数参数说明:

pattern 匹配的正则表达式

string 要匹配的字符串。

flags 标志位,用于控制正则表达式的匹配方式,如:是否区分,多行匹配等等。

13.2.1 举例1:

代码语言:javascript
复制
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

import re
print(re.match('www', 'www.google.com'))
print(re.match('www', 'www.google.com').span())
print(re.match('google', 'www.google.com'))

括号中第一个'www'是正则表达式,相当于匹配的规则; 后面是要匹配的字符串内容。

image_1c0bl8htnbsm16lhccj1ado14901sp.png-5.3kB
image_1c0bl8htnbsm16lhccj1ado14901sp.png-5.3kB

第一个结果可以看到从起始位置匹配到了'www'

第二个结果来输出匹配到内容的下标位置

第三个结果是none,这是因为在www.google.com中不是以google为起始位置的,所以匹配不到。

13.2.2 举例:

代码语言:javascript
复制
import re

line = "Cats are smarter than dogs"

matchObj = re.match( r'(.*) are (.*?) .*', line)    

#将line这个变量作为一个需要匹配的内容;

#这里正则表达式通过()分了两个部分,可以用group来表达,在are之前的(.*)是一部分,在are之后的(.*?) 一个部分,如果去掉的话匹配结果就不同了。

每一个()表示一个分组

if matchObj:
    print ("matchObj.group() : ", matchObj.group())    #匹配所有()和非()表达式中的内容
    print ("matchObj.group(1) : ", matchObj.group(1))    #匹配第一个()中的表达式内容
    print ("matchObj.group(2) : ", matchObj.group(2))    #匹配第二个()中的表达式内容
    print ("matchObj.group(3) : ", matchObj.groups())    #匹配所有()中的表达式美容,并以元组的形式显示
else:
print ("No match!!")
image_1c0bl9gdj11rt1pn6g0p1pli1ngt1t6.png-6.8kB
image_1c0bl9gdj11rt1pn6g0p1pli1ngt1t6.png-6.8kB

13.3 正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

image_1c0bl9vv9nsojf1r7h5og12gf1tj.png-24.7kB
image_1c0bl9vv9nsojf1r7h5og12gf1tj.png-24.7kB

13.4 正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'/t',等价于'//t')匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

image_1c0blaf8qeve1rl51vuf3871ib21u0.png-57.1kB
image_1c0blaf8qeve1rl51vuf3871ib21u0.png-57.1kB
image_1c0blatem1mfg1c0s1lja153c1jui1ud.png-58.4kB
image_1c0blatem1mfg1c0s1lja153c1jui1ud.png-58.4kB
image_1c0blb49d1dfo2tm1vi31n3f17gi1uq.png-22.9kB
image_1c0blb49d1dfo2tm1vi31n3f17gi1uq.png-22.9kB

13.5 正则表达式实例

image_1c0blbpa6nmv9q0tsp12nn19rn1v7.png-32.6kB
image_1c0blbpa6nmv9q0tsp12nn19rn1v7.png-32.6kB
image_1c0blc05bg5svc7chv1ssq73c1vk.png-31.7kB
image_1c0blc05bg5svc7chv1ssq73c1vk.png-31.7kB

13.6 使用模式举例

  • 使用:'.'
代码语言:javascript
复制
line = 'www.google.com'
rule = re.match(r'.',line)
print (rule)
print (rule.group())
image_1c0bldjoj1qic1i6375d1lsh154v21h.png-4.3kB
image_1c0bldjoj1qic1i6375d1lsh154v21h.png-4.3kB

使用一个'.'表达除了\n 外的任意一个字符(字母、数字、特殊字符),可以看到职匹配了第一个w

不使用group来表达的话会多现实一些参数,比如span表达了第一个w所在下标的位置范围

  • 使用:'.+'
代码语言:javascript
复制
line = 'www.google.com'

rule = re.match(r'.+',line)
image_1c0blducmgd8qa217mp1ul01on021u.png-1.4kB
image_1c0blducmgd8qa217mp1ul01on021u.png-1.4kB

'.+'通过'+'匹配了0个或多个'.'

  • 使用:'w','w+'
代码语言:javascript
复制
rule1 = re.match(r'w',line)    #匹配一个字母
rule2 = re.match(r'w+',line)    #匹配1或多个字母
rule3 = re.match(r'w{2}',line)    #匹配2个字母
rule4 = re.match(r'w{1,3}',line)    #匹配1到3个字母(至少1个,最多3个)

print (rule1.group())
print (rule2.group())
print (rule3.group())
print (rule4.group())
image_1c0blev5v12ess0ied86rjja722b.png-0.7kB
image_1c0blev5v12ess0ied86rjja722b.png-0.7kB

匹配了字母,遇见'.'后不符合表达式(不属于字母),所以连带'.'后面的所有内容也都不匹配了。

代码语言:javascript
复制
rule5 = re.match(r'w+|.+',line)
rule6 = re.match(r'.+|w+',line)
image_1c0blfk381h8s1f5s1vbf1egcvn022o.png-1.7kB
image_1c0blfk381h8s1f5s1vbf1egcvn022o.png-1.7kB

通过|来表示或的意思,但是在匹配的时候,只要前面的规则匹配到了,后面就不在匹配了,所以可以看到匹配的结果不同。

  • 使用:‘search’
代码语言:javascript
复制
re.search('www','www.google.com').group()    #注意匹配www时是没有使用r或\转义的,所以匹配的就是www字符本身

re.search('google','www.google.com').group()
image_1c0blg77913urboo1sv3c7c1k40235.png-8.9kB
image_1c0blg77913urboo1sv3c7c1k40235.png-8.9kB

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

  • 使用:‘d’
代码语言:javascript
复制
re.search('(\d{3})(\d{4})','123456789123456789').groups()
image_1c0blgqhrmmc1pci1s13hl0mmh23i.png-6.3kB
image_1c0blgqhrmmc1pci1s13hl0mmh23i.png-6.3kB

匹配数字,因为有两个(),所以在元组中分为两个元素显示

使用:‘^,$,Z’

image_1c0blhhnd5j2194s1bst1lpc1st523v.png-19kB
image_1c0blhhnd5j2194s1bst1lpc1st523v.png-19kB

通过^匹配以数字开头的,通过$匹配以数字结尾的,第一个报错是因为匹配的内容不是数字结尾,另一个匹配则是以数字为结尾所以不会报错。

Z与$是一个意思

  • 列表项
代码语言:javascript
复制
rule = re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}','192.168.1.1').group()
print (rule)
image_1c0bllfe512of1k01sa11e14102424c.png-1.2kB
image_1c0bllfe512of1k01sa11e14102424c.png-1.2kB
代码语言:javascript
复制
rule = re.search('(\d{1,3}\.){3}\d{1,3}','192.168.1.1').group()    #稍微优化
print (rule)
image_1c0blm0mddub11jg1ef6c1u1oe824p.png-1.2kB
image_1c0blm0mddub11jg1ef6c1u1oe824p.png-1.2kB
代码语言:javascript
复制
rule = re.search('([0-2]?[0-9]?[0-9]+\.){3}[0-2]?[0-9]?[0-9]','192.168.1.1').group()
print (rule)
image_1c0blmmi310n71b951rimoo41pa9256.png-1.2kB
image_1c0blmmi310n71b951rimoo41pa9256.png-1.2kB

以上都不是合法的IP地址写法

  • 匹配:合法IP地址
代码语言:javascript
复制
rule = re.search('^((25[0-5]|2[0-4]\d|[1]?\d?\d)\.){3}(25[0-5]|2[0-4]\d|[1]?\d?\d)$','255.168.1.255').group()
print (rule)
image_1c0blnhr51jo1gd8rj5gld4ll25j.png-1.2kB
image_1c0blnhr51jo1gd8rj5gld4ll25j.png-1.2kB
代码语言:javascript
复制
rule = re.search('^((25[0-5]|2[0-4]\d|[1]?\d?\d)\.){3}(25[0-5]|2[0-4]\d|[1]?\d?\d)$','256.168.1.255').group()        #第一个IP被协成256,这是不合法的

print (rule)
image_1c0blo0mka38741h8l1cth65k260.png-17.2kB
image_1c0blo0mka38741h8l1cth65k260.png-17.2kB

可以看到报错

  • 使用:'re.findall'
代码语言:javascript
复制
rule1 = re.search('\d+','ab13aa22cc334bb44adsf234656').group()
rule2 = re.findall('\d+','ab13aa22cc334bb44adsf234656')    #这里不需要group
print (rule1)
print (rule2)
image_1c0blot4i1hku1ng6g9n14p5qem26d.png-2.3kB
image_1c0blot4i1hku1ng6g9n14p5qem26d.png-2.3kB

可以看到search只能寻找其中一个,而findall可以寻找所有。

代码语言:javascript
复制
rule3= re.findall('\D+','ab13aa22cc334bb44adsf234656')

print (rule3)
image_1c0blpcfad3o12ct7f51722e4l26q.png-1.6kB
image_1c0blpcfad3o12ct7f51722e4l26q.png-1.6kB

\D表示非数字

  • 使用:'re.split' rule1 = re.split('\d+','ab13aa22cc334bb44adsf234656') print (rule1)
image_1c0blq4o0b293161a42fd11bs9277.png-2.1kB
image_1c0blq4o0b293161a42fd11bs9277.png-2.1kB
  • 使用re.split分隔成列表显示

可以看到与findall类似,但是split后面因为有数字所以就分隔了一个空

代码语言:javascript
复制
rule1 = re.split('\d+','ab13aa22cc334bb44adsf234656dd')    #最后面加个dd字符串
print (rule1)
image_1c0blqv1h15uljmv3q1m8og7s27k.png-1.7kB
image_1c0blqv1h15uljmv3q1m8og7s27k.png-1.7kB

使用re.split分隔成列表显示

可以看到与findall类似,但是split后面因为有数字所以就分隔了一个空

代码语言:javascript
复制
rule1 = re.split('\d+','ab13aa22cc334bb44adsf234656dd')    #最后面加个dd字符串
print (rule1)
image_1c0blrqj61c51cps1omd1lkr7bd281.png-1.7kB
image_1c0blrqj61c51cps1omd1lkr7bd281.png-1.7kB

会将dd进行分隔

  • 使用:re.sub
代码语言:javascript
复制
rule = re.sub('\d+','|','ab13aa22cc334bb44adsf234656dd')
print (rule)
image_1c0blst921gpudlh6u51mth6gv28e.png-1.2kB
image_1c0blst921gpudlh6u51mth6gv28e.png-1.2kB

使用re.sub进行替换,将数字替换成 |

代码语言:javascript
复制
rule = re.sub('\d+','XXX','ab13aa22cc334bb44adsf234656dd',count=2)
print (rule)
image_1c0bltm7d13on5bc1ou627o1q9p28r.png-2.4kB
image_1c0bltm7d13on5bc1ou627o1q9p28r.png-2.4kB

count是替换几次

  • flags rule = re.search('a+','AAAaaa').group() print (rule)
image_1c0bm05dg16056fl15c7c961arm2b8.png-0.3kB
image_1c0bm05dg16056fl15c7c961arm2b8.png-0.3kB

只能匹配到小写的a

代码语言:javascript
复制
rule = re.search('a+','AAAaaa',re.I).group()
print (rule)
image_1c0bm0026igglte16si1n6q1sn52ar.png-0.5kB
image_1c0bm0026igglte16si1n6q1sn52ar.png-0.5kB

使用falgs中的re.I可以忽略大小写


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-08-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模块的分类
  • 标准库
    • 1.time
      • 2.datetime
        • 3.random模块
          • 4.OS模块
            • 5. sys与shutil模块
              • 6. shutil模块
                • 7. json、pickle、shelve
                  • 8. xml处理模块
                    • 9. PyYAML和configparser
                      • 10. hashlib
                        • 11. subprodcess
                          • 12. logging
                            • 13. re正则表达式模块
                            相关产品与服务
                            日志服务
                            日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档