Python23 内置模块讲解

2023-01-31 02:01:21 模块 讲解 Python23

模块的分类

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

python中的模块分为三大类:

1.标准库(内置模块)

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

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

标准库

1.time

UTC是世界标准时间,中国是在东8区(GMT+8)
image_1c0bi1c1j1pkr1rn91ovspjf1omo9.png-4.6kB
导入time模块,通过time.timezone查看时区,28800是秒单位,除60是分钟,在除60的结果是小时,也就是说中国时区比UTC早8个小时。

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

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

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

1.3 time.gmtime
image_1c0bi3mtd4ki1rgt12fvhoka4e1t.png-6.7kB
以元组的方式转换时间戳,显示转换的时间,默认显示的是当前UTC的时间(不是中国东八区时间),比东八区差了8个小时。

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

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

1.4 time.localtime

image_1c0bi5qjai2j1ken227chthjt3h.png-6.6kB
以元组的方式转换时间戳,显示的是本地的时间。

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

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

1.5 time.mktime
image_1c0bi7328c3qj6n8h69bo1snk4o.png-2.7kB
将具体的格式时间转换为时间戳

1.6 time.strftime与time.strptime

time.strftime用于将具体格式时间转换为格式化的字符串时间
image_1c0bi7ig9t5f9pp144o1f0p5nj55.png-63.7kB
通过help查看用法,可以看到%符号后面对应字母所代表的内容,图中红线部分是使用格式。

image_1c0bi7vd21ov0uisg5714rc1shg5i.png-4.6kB
%Y:年
%m:月
%d:日
%H:小时
%M:分钟
%S:秒

image_1c0bi8ktmssm1r8jtj4u1hasv5v.png-61kB
strptime的使用格式
strptime是用来将字符串转为具体的格式时间

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

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

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

1.7 time.asctime
image_1c0bianj0dedhi214cm1r1lqq17j.png-19.3kB

image_1c0bias9n1l9974h9njdi6106a80.png-3.5kB
用英文的方式进行表示(将元组的格式事件转换为英文时间格式)

image_1c0bib8gnbuv17er2dji2oa3r8d.png-3.7kB

1.8 time.ctime

用于将时间戳转换为英文时间格式
image_1c0bibknfqd91ojs17671eh1k7f8q.png-9.8kB


2.datetime

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

image_1c0bici7tr8jotq6is15nn1def97.png-4.6kB
获取现在的时间

image_1c0bics6ehj5567qn0cfn7s99k.png-9.6kB
显示根据当前时间+3天;显示根据当前时间-3天

image_1c0bidam5djm1mh0125r7irm95a1.png-10.7kB
前后的小时 时间


3.random模块

3.1 random.random
Python23 内置模块讲解

随机获取浮点数

3.2 random.randint
image_1c0bieb2um9uquv1cmc1vu2q7qar.png-12.5kB
随机获取指定的整数

3.3 random.randrange
image_1c0bien86ad11rh9021n8scnb8.png-13.5kB
使用randrange和range类似,最后一个数字不算

3.4 random.choice
image_1c0bif49i1g9goma1ovhe9912kbl.png-20.2kB
在不同的数据类型中随机选值

3.5 radom.sample
image_1c0big5tn14abk9j1vf2fv01u0oc2.png-14.2kB
随机取两个值

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

3.7 random.shuffle(洗×××功能)
image_1c0bihqs5131lh910gk1nfgpqmcs.png-5kB
把顺序打乱

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

import random

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

image_1c0bijapt16v2ej91ug01gju14aod9.png-0.7kB

3.8.2使用数字+字母验证
image_1c0bijkuqskr17tshu3036lodm.png-2.6kB
chr65到69 一 一对应了A-Z字母

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

字母+数字的随机验证码


4.OS模块

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

os用于调取系统命令

4.1 os.getcwd
image_1c0bilu6c1cgiu351k6h7dra9eg.png-5.2kB
获取当前操作目录

4.2 os.chdir
image_1c0bimdeb1d2s1j2t1dg21u8k1tonet.png-4.4kB
切换操作目录
c:后面是两个\,第一个\是转译符,使用\只能转译后面的一个符号

image_1c0bin1jl1hmpcaf571vqipunfa.png-7.7kB

通过用r来转义

4.3 os.curdir

image_1c0binjejnbenno1e231nqnek1fn.png-1.5kB

返回当前目录

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

4.4 os.pardir
image_1c0bip3fam0a1pu819kl1m1npf3g4.png-1.5kB
返回上级目录

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

4.5 os.makedirs与 os.removedirs
4.5.1
image_1c0bipq7lc3d1brj1olr18c1cc8gh.png-2.9kB
在D盘先建立a目录,在a目录中建立b目录,以此类推

image_1c0biq44ifjr1ffe1v2oqt8h1gu.png-7.9kB
makedirs可以建立多个目录

4.5.2
image_1c0bisl0f1v4p1o1sjdk1m881j9thr.png-6.5kB
在a目录中建立一个文档

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

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

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

4.6 os.mkdir
mkdir也是用于建立目录的,只不过是建立单个目录的
image_1c0bj1gu11a331ou15teheq1r4tjf.png-11.1kB
建立多个目录失败

image_1c0bj1r2mditgbv1rc63063vdjs.png-2.3kB

image_1c0bj1vtteng7qrqqgire16m9k9.png-6.5kB
建立单个目录,建立多级目录的话,需要一个一个的去建立

4.7 os.rmdir
image_1c0bj2iv61dfc2u57lj9h75pkkm.png-3.5kB
将原有的目录删除,重新建立,然后通过rmdir删除,只会删除一个目录,不会删除多个。
image_1c0bj49811nkr9f41n9l1msvmsrmg.png-4.7kB

4.8 os.listdir
image_1c0bj431l1tdrdrsn3nmd4afm3.png-10.8kB
以列表的方式列出当前目录有哪些内容

‘.’表示当前目录

默认也是列出当前目录

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

4.12 os.sep

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

linux中路径是用左斜杠/来表示分隔
image_1c0bj5sd11s1o38b1nmg1pr3i4nn.png-18.6kB

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

4.13 os.linesep
image_1c0bj67giohb36b71s13ad1j6po4.png-1.7kB
换行符是\r\n

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

4.15 os.name
image_1c0bj8q52kj31hgh7j6aii18sopb.png-1.5kB

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

4.16 os.system

用来执行当前系统的命令
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
以元组的方式显示,将目录和文件分隔开。

4.17.3 os.path.dirname与os.path.basename
image_1c0bjaqd1aaplif1eqh7q1unkqi.png-10kB
一个取目录名,一个结尾的。

4.17.4 os.path.exist
image_1c0bjbbhm1rp1g5b1ja31n811eqjqv.png-2.6kB
判断路径是否存在

4.17.5 os.path.isabs
image_1c0bjce57l1b27a1ptj1ieatnors.png-2.8kB
判断是否是以根开头的绝对路径
在Windows中每个盘符都是根,在linux中/是根
如果False的话就是相对路径

4.17.6 os.path.isfile与 os.path.isdir
image_1c0bjet2f14qbkr416vb17io12p2s9.png-5.7kB
判断是否是一个文件

image_1c0bjf7g71tr21746s0h1u2t12pnsm.png-2.8kB
判断是否是目录

4.17.7 os.path.join
image_1c0bjgf4j1q7eu04c1r1v2uu0lt3.png-4.3kB
将目录与文件组合并返回

4.17.8 os.path.getatime与 os.path.getmtime
image_1c0bjguheji37n6g2r1m07594tg.png-6.9kB
获取文件的最后存取时间,时间格式为时间戳
image_1c0bjha236ln1ckt1ups1kqoqqstt.png-6.9kB
获取修改时间


5. sys与shutil模块

sys模块没有细讲,请单独翻阅资料
5.1 sys.version
image_1c0bji91j1kg81f69154j10s71nagua.png-8.1kB
获取当前python的版本信息

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


6. shutil模块

shutil用于copy文件用的

6.1 shutil.copyfileobj

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
成功的将test1中的内容copy到test2

6.2 shutil.copyfile

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

image_1c0bjn7at9mg1hkm1aceb0k15pt101.png-7.3kB

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

6.4 shutil.copystat
image_1c0bjnjkf57o1nu2vce14jitl10e.png-4.1kB
只copy了权限

6.5 shutil.copytree与shutil.rmtree
image_1c0bjo3dgsa21lqq12i21bsq1v5210r.png-19.2kB

image_1c0bjo8tr1t61v3ni3o5ee1hjj118.png-20.4kB

6.6 shutil.make_arvHive
image_1c0bjoiqr1fgcc48flo15mo1sgg11l.png-3.5kB

image_1c0bjp4qm1dkr1qfks8kjnl2j2122.png-19.9kB
默认在当前操作目录

image_1c0bjpfd5asvrjb1j8joh188h12f.png-6.8kB

image_1c0bjpmb812ja17m31buts8hqtg12s.png-2.1kB
指定目录

6.7 zipfile、tarfile

import zipfile

压缩

z = zipfile.ZipFile('laxi.zip', 'w')

z.write('a.log')

z.write('data.data')

z.close()

解压

z = zipfile.ZipFile('laxi.zip', 'r')

z.extractall()

z.close() 

压缩

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()

解压

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之前整理过,可以在不同的语言或系统平台进行数据的转换

只支持部分数据类型

s1={"k1":"v1"}

st=json.dumps(s1)

print(st,type(st))

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

dic=json.loads(s)

print(dic,type(dic)) 
输出结果为:

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

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

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

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

li=[11,22,33]

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

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

print(li,type(li)) 
输出结果为:

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

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

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

7.2 pickle

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

支持全部数据类型

import pickle

i=[11,22,33]

r=pickle.dumps(li)

print(r)

result=pickle.loads(r)

print(result) 
 结果为:

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

[11, 22, 33] 

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

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

import pickle

i=[11,22,33]

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

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

print(result) 

    结果为:

[11, 22, 33]

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

7.3 shelve

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

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']) 

结果为:

www.baidu.com

www.qq.com

www.360.cn 

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

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
这是一个xml文件的内容

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
将第一行的data给打印出来了

遍历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_1c0bk31imjaqi9k20enh8pr714g.png-14.7kB

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

image_1c0bk3g9sssm1v2l4601tvb50314t.png-3.2kB

i.tag表示rank(标签名)

i.text表示2 (值)

i.attrib表示updated="yes"> (属性)
只遍历year 节点
for node in root.iter('year'):
    print(node.tag, node.text)

image_1c0bk4kh21kev18nh8qa1m8d8do15q.png-1.7kB

8.2 xml修改

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
可以看到源文件中的year值都加了一年

8.3 删除
image_1c0bk5omclpk1gdo1qrq1h5lf16k.png-37.1kB
删除之前有一个叫Panama的country

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
已经看不到Panama这个country了

8.4 创建

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
可以看到生成的xml文件,只不过默认格式不对,需要手动调整一下。

image_1c0bk91cmoa41peh4g1n8p7aj18e.png-34.4kB
调整后的文件


9. PyYAML和configparser

9.1 PyYAML

PyYAML是用来做配置文件的

9.2 configparser

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

python3的写法:configparser

python2的写法:ConfigParser

9.2.1 写入

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

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

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

9.2.2 读取

import configparser

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

print(conf.defaults())    

image_1c0bkc815nst6m1e661a9oe741a5.png-4.8kB

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

print(conf['bitbucket.org']['user'])

image_1c0bkcl3mqjm76t1shv17rfp641ai.png-0.5kB
其他的节点只能通过字典的方式来调用

sec = conf.remove_section('bitbucket.org')    #删除指定节点
conf.write(open('example.ini', "w"))    #写入

image_1c0bkd6vlfq01pebk4v18vnmlt1av.png-14.1kB


10. hashlib

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

10.1 MD5

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

第一个生成的MD5是Hello

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

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

image_1c0bke7bg1u7r1r6t1fv21hlj1jh11bp.png-20.3kB

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

10.2 sha

m3 = hashlib.sha3_512()
m3.update(b'HelloIts me')
print (m3.hexdigest())

image_1c0bkfkun1anc10kljrq19io1pgq1cj.png-15.2kB

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

10.3 hMac

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

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

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

import hmac
h = hmac.new(b'12345',b'qwerasdf')   #abc123是key,1234qwer是消息,
print (h.hexdigest())

image_1c0bkg34d1psdvb7ivm2hk1bpt1d0.png-2.8kB

image_1c0bkg9efd92t111umb1asp79b1dd.png-13.3kB

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

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

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)
示例如下:


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时,直接抛出异常


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)

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)

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。

使用如下方法:


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)
将一个子进程的输出,作为另一个子进程的输入:


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)


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 日志级别信息输出

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

logging.basicConfig(filename='app.log',level=logging.DEBUG)   

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

image_1c0bkithj173f3g1up9q1a10p51fe.png-8.7kB
可以看到新增代码后,就不在pycharm中输出日志信息了

image_1c0bkl9qgk8b1ua1aon5jk13791fr.png-28.5kB
根据指定的app.log文件,将信息输出到文件中。

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

image_1c0bkmfto1o8tnj1lm61l1r13jf1gl.png-26kB
将WARNING级别以及比其高的级别日志信息输出
image_1c0bkmpdn1bf7e1m6oc1tkuue21h2.png-12.1kB

12.3 添加日志格式

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_1c0bkrbqa85l1fgp1l1a866sri1k9.png-42.9kB

image_1c0bkr6gptgcde569016kas521js.png-15.7kB
定义日志格式,让其显示日志级别
image_1c0bkrjeb1gjsni19bt147i1pvg1km.png-12.4kB

image_1c0bkrqmc12861usn1k81180icta1l3.png-16.4kB
显示输出的文件名

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

image_1c0bkshlk18rvi6n12ea1iq45901lt.png-16.9kB
使用%(lineno)d可以显示输出文档的行号
image_1c0bkssbuj2p19hhajt17be2r21ma.png-17.5kB
可以看到该日志信息是通过哪个文档的哪一行输出的。

image_1c0bkt6lduufgsr1lon3n9maa1mn.png-17kB
%(funcName)s显示生成日志的函数名称

image_1c0bktgim1iodlkj1786umi18us1n4.png-7.8kB

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”)

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

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)输出信息。它的构造函数是:

    StreamHandler([strm])
    其中strm参数是一个文件对象。默认是sys.stderr

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

    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输出到多个目的

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
输出到屏幕的告警信息,因为定义的最低告警级别是warning,所以两个级别的信息都可以看到

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

12.4.2.2 按大小自动截断

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

image_1c0bl5m6nmvp1stm1mve7du1u151ri.png-12.5kB
log.1是最接近主文件的内容的,所以是'test5'

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

12.4.2.3 按时间自动截断

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
从第5秒开始截断的


13. re正则表达式模块

13.1 函数语法:

re.match(pattern,string, flags=0) 

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

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

13.2 re.match函数

函数参数说明:

pattern 匹配的正则表达式

string 要匹配的字符串。

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

13.2.1 举例1:

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

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

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

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

13.2.2 举例:

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

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

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

image_1c0bl9vv9nsojf1r7h5og12gf1tj.png-24.7kB

13.4 正则表达式模式

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

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

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

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

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

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

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

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

13.5 正则表达式实例
image_1c0blbpa6nmv9q0tsp12nn19rn1v7.png-32.6kB
image_1c0blc05bg5svc7chv1ssq73c1vk.png-31.7kB

13.6 使用模式举例

  • 使用:'.'
line = 'www.google.com'
rule = re.match(r'.',line)
print (rule)
print (rule.group())

image_1c0bldjoj1qic1i6375d1lsh154v21h.png-4.3kB

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

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

  • 使用:'.+'
line = 'www.google.com'

rule = re.match(r'.+',line)

image_1c0blducmgd8qa217mp1ul01on021u.png-1.4kB

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

  • 使用:'w','w+'
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

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

rule5 = re.match(r'w+|.+',line)
rule6 = re.match(r'.+|w+',line)

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

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

re.search('google','www.google.com').group()

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

  • 使用:‘d’
re.search('(\d{3})(\d{4})','123456789123456789').groups()

image_1c0blgqhrmmc1pci1s13hl0mmh23i.png-6.3kB
匹配数字,因为有两个(),所以在元组中分为两个元素显示

使用:‘^,$,Z’
image_1c0blhhnd5j2194s1bst1lpc1st523v.png-19kB
通过^匹配以数字开头的,通过$匹配以数字结尾的,第一个报错是因为匹配的内容不是数字结尾,另一个匹配则是以数字为结尾所以不会报错。

Z与$是一个意思

  • 列表项
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

rule = re.search('(\d{1,3}\.){3}\d{1,3}','192.168.1.1').group()    #稍微优化
print (rule)

image_1c0blm0mddub11jg1ef6c1u1oe824p.png-1.2kB

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

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

  • 匹配:合法IP地址
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

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
可以看到报错

  • 使用:'re.findall'
rule1 = re.search('\d+','ab13aa22cc334bb44adsf234656').group()
rule2 = re.findall('\d+','ab13aa22cc334bb44adsf234656')    #这里不需要group
print (rule1)
print (rule2)

image_1c0blot4i1hku1ng6g9n14p5qem26d.png-2.3kB
可以看到search只能寻找其中一个,而findall可以寻找所有。

rule3= re.findall('\D+','ab13aa22cc334bb44adsf234656')

print (rule3)

image_1c0blpcfad3o12ct7f51722e4l26q.png-1.6kB
\D表示非数字

  • 使用:'re.split'

    rule1 = re.split('\d+','ab13aa22cc334bb44adsf234656')
    print (rule1)

    image_1c0blq4o0b293161a42fd11bs9277.png-2.1kB

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

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

rule1 = re.split('\d+','ab13aa22cc334bb44adsf234656dd')    #最后面加个dd字符串
print (rule1)

image_1c0blqv1h15uljmv3q1m8og7s27k.png-1.7kB

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

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

rule1 = re.split('\d+','ab13aa22cc334bb44adsf234656dd')    #最后面加个dd字符串
print (rule1)

image_1c0blrqj61c51cps1omd1lkr7bd281.png-1.7kB
会将dd进行分隔

  • 使用:re.sub
rule = re.sub('\d+','|','ab13aa22cc334bb44adsf234656dd')
print (rule)

image_1c0blst921gpudlh6u51mth6gv28e.png-1.2kB
使用re.sub进行替换,将数字替换成 |

rule = re.sub('\d+','XXX','ab13aa22cc334bb44adsf234656dd',count=2)
print (rule)

image_1c0bltm7d13on5bc1ou627o1q9p28r.png-2.4kB
count是替换几次

  • flags
    rule = re.search('a+','AAAaaa').group()
    print (rule)

    image_1c0bm05dg16056fl15c7c961arm2b8.png-0.3kB
    只能匹配到小写的a

rule = re.search('a+','AAAaaa',re.I).group()
print (rule)

image_1c0bm0026igglte16si1n6q1sn52ar.png-0.5kB

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


相关文章