设为首页 收藏本站
查看: 543|回复: 0

[经验分享] Python23 内置模块讲解

[复制链接]

尚未签到

发表于 2018-8-4 10:55:09 | 显示全部楼层 |阅读模式
模块的分类
  参考博客http://www.cnblogs.com/alex3714/articles/5161349.html
  python中的模块分为三大类:
  

1.标准库(内置模块)  

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

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

标准库

1.time
  UTC是世界标准时间,中国是在东8区(GMT+8)
  ![image_1c0bi1c1j1pkr1rn91ovspjf1omo9.png-4.6kB][1]
  导入time模块,通过time.timezone查看时区,28800是秒单位,除60是分钟,在除60的结果是小时,也就是说中国时区比UTC早8个小时。
  1.1 time.time
  ![image_1c0bi20qd1hi61lm35m416qd5e7m.png-2.3kB][2]
  time.time()查看时间戳,以秒为单位,这个数字实际没什么大的意义,只不过是从1970年开始算起到当前经历了多少秒。从1970年开始算是因为这是Unix诞生的时间。
  ![image_1c0bi2huj107sqhj1vej9ifle713.png-5.9kB][3]
  1507535507/60/60/24/365(最终求的是多少年),结果是从1970年到现在为47年,1970+47就是今年的2017年。
  1.2 time.sleep
  ![image_1c0bi30g51bnvevd1391asr7ug1g.png-1.6kB][4]
  用于延迟,图中定义了延迟3秒
  在写代码时,可以利用time.sleep延迟多久后在继续执行后续的代码。
  1.3 time.gmtime
  ![image_1c0bi3mtd4ki1rgt12fvhoka4e1t.png-6.7kB][5]
  以元组的方式转换时间戳,显示转换的时间,默认显示的是当前UTC的时间(不是中国东八区时间),比东八区差了8个小时。
  时间格式为:年、月、日、小时、分钟、秒、本周第几天(从0开始算)、本年第几天(1-366)、是否是夏令时
  ![image_1c0bi434g1v2n1aprg9kqrk1te72a.png-7.6kB][6]
  在括号中输入以秒为单位的数字进行计算UTC的时间(从1970年开始算)
  1.4 time.localtime
  ![image_1c0bi5qjai2j1ken227chthjt3h.png-6.6kB][7]
  以元组的方式转换时间戳,显示的是本地的时间。
  ![image_1c0bi688v11i51g2c1l051srqupe3u.png-10kB][8]
  元组中的时间数据类似字典,当想要取出时间时,取对应的key就可以看到相应的value
  ![image_1c0bi6hjnh7a1v11ut31ul1gmm4b.png-14.9kB][9].
  取出指定时间戳,显示是哪年的第多少天。
  1.5 time.mktime
  ![image_1c0bi7328c3qj6n8h69bo1snk4o.png-2.7kB][10]
  将具体的格式时间转换为时间戳
  1.6 time.strftime与time.strptime
  time.strftime用于将具体格式时间转换为格式化的字符串时间
  ![image_1c0bi7ig9t5f9pp144o1f0p5nj55.png-63.7kB][11]
  通过help查看用法,可以看到%符号后面对应字母所代表的内容,图中红线部分是使用格式。
  ![image_1c0bi7vd21ov0uisg5714rc1shg5i.png-4.6kB][12]
  %Y:年
  %m:月
  %d:日
  %H:小时
  %M:分钟
  %S:秒
  ![image_1c0bi8ktmssm1r8jtj4u1hasv5v.png-61kB][13]
  strptime的使用格式
  strptime是用来将字符串转为具体的格式时间
  ![image_1c0bi9cgi81eu0q1g05hsubln6c.png-10.4kB][14]
  strptime是与strftime相反的功能,这里用逗号隔开的两边内容格式要一 一对应,2017对应%Y,10对应%m,这里位置上的联系一定要对应。
  ![image_1c0bi9udvbi1l0ikkf1jea1fs16p.png-9.6kB][15]
  strftime使用时间格式默认就是本地时间,可以通过指定其他的时间来输出字符串格式的时间,time.localtime相当于给这个格式赋值
  ![image_1c0bia92f9cg17kj19fchbliiq76.png-13kB][16]
  调整格式的位置,输出的字符串时间格式也会随着改变
  当前的x相当于2017-10-11 xx:xx:xx,而格式没有与该时间想对应,说明使用strftime在位置上的格式是没有联系的
  1.7 time.asctime
  ![image_1c0bianj0dedhi214cm1r1lqq17j.png-19.3kB][17]
  ![image_1c0bias9n1l9974h9njdi6106a80.png-3.5kB][18]
  用英文的方式进行表示(将元组的格式事件转换为英文时间格式)
  ![image_1c0bib8gnbuv17er2dji2oa3r8d.png-3.7kB][19]
  1.8 time.ctime
  用于将时间戳转换为英文时间格式
  ![image_1c0bibknfqd91ojs17671eh1k7f8q.png-9.8kB][20]

2.datetime
  datetime.date 获取年月日
  datetime.time 获取时分秒
  datetime.datetime 获取年月日时分秒
  ![image_1c0bici7tr8jotq6is15nn1def97.png-4.6kB][21]
  获取现在的时间
  ![image_1c0bics6ehj5567qn0cfn7s99k.png-9.6kB][22]
  显示根据当前时间+3天;显示根据当前时间-3天
  ![image_1c0bidam5djm1mh0125r7irm95a1.png-10.7kB][23]
  前后的小时 时间

3.random模块
  3.1 random.random
  ![image_1c0bidt661st9ltc1tng6dbkuoae.png-8.9kB][24]
  随机获取浮点数
  3.2 random.randint
  ![image_1c0bieb2um9uquv1cmc1vu2q7qar.png-12.5kB][25]
  随机获取指定的整数
  3.3 random.randrange
  ![image_1c0bien86ad11rh9021n8scnb8.png-13.5kB][26]
  使用randrange和range类似,最后一个数字不算
  3.4 random.choice
  ![image_1c0bif49i1g9goma1ovhe9912kbl.png-20.2kB][27]
  在不同的数据类型中随机选值
  3.5 radom.sample
  ![image_1c0big5tn14abk9j1vf2fv01u0oc2.png-14.2kB][28]
  随机取两个值
  3.6 random.uniform
  random.random默认只能取值0-1的浮点数,可以通过random.uniform来指定浮点数范围
  ![image_1c0bigmvoepf10roneo11nq1etacf.png-20.1kB][29]
  3.7 random.shuffle(洗牌功能)
  ![image_1c0bihqs5131lh910gk1nfgpqmcs.png-5kB][30]
  把顺序打乱
  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][31]
  3.8.2使用数字+字母验证
  ![image_1c0bijkuqskr17tshu3036lodm.png-2.6kB][32]
  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][33]
  字母+数字的随机验证码

4.OS模块
  http://python.usyiyi.cn/translate/python_278/library/os.html
  os模块使用参考网址
  os用于调取系统命令
  4.1 os.getcwd
  ![image_1c0bilu6c1cgiu351k6h7dra9eg.png-5.2kB][34]
  获取当前操作目录
  4.2 os.chdir
  ![image_1c0bimdeb1d2s1j2t1dg21u8k1tonet.png-4.4kB][35]
  切换操作目录
  c:后面是两个\,第一个\是转译符,使用\只能转译后面的一个符号
  ![image_1c0bin1jl1hmpcaf571vqipunfa.png-7.7kB][36]
  通过用r来转义
  4.3
  图中的os.xxx在该博客属于违规内容无法输入
  ![image_1c0binjejnbenno1e231nqnek1fn.png-1.5kB][37]
  返回当前目录
  一个点'.'表示当前目录
  4.4 os.pardir
  ![image_1c0bip3fam0a1pu819kl1m1npf3g4.png-1.5kB][38]
  返回上级目录
  两个'..' 两个点表示上级目录
  4.5 os.makedirs与 os.removedirs
  4.5.1
  ![image_1c0bipq7lc3d1brj1olr18c1cc8gh.png-2.9kB][39]
  在D盘先建立a目录,在a目录中建立b目录,以此类推
  ![image_1c0biq44ifjr1ffe1v2oqt8h1gu.png-7.9kB][40]
  makedirs可以建立多个目录
  4.5.2
  ![image_1c0bisl0f1v4p1o1sjdk1m881j9thr.png-6.5kB][41]
  在a目录中建立一个文档
  ![image_1c0bitgst1aav7121lt2ge71q6kil.png-2.7kB][42]
  ![image_1c0bitle91v3i73g7ckdbafgtj2.png-5.7kB][43]
  可以看到除了D盘和a目录,其他目录都被删除了;这是因为使用os.removedirs是删除空的目录,当前D盘和a目录都是非空
  removedirs是递归的删除,只要上一层目录为空就删除,会删掉多个空的目录
  4.6 os.mkdir
  mkdir也是用于建立目录的,只不过是建立单个目录的
  ![image_1c0bj1gu11a331ou15teheq1r4tjf.png-11.1kB][44]
  建立多个目录失败
  ![image_1c0bj1r2mditgbv1rc63063vdjs.png-2.3kB][45]
  ![image_1c0bj1vtteng7qrqqgire16m9k9.png-6.5kB][46]
  建立单个目录,建立多级目录的话,需要一个一个的去建立
  4.7 os.rmdir
  ![image_1c0bj2iv61dfc2u57lj9h75pkkm.png-3.5kB][47]
  将原有的目录删除,重新建立,然后通过rmdir删除,只会删除一个目录,不会删除多个。
  ![image_1c0bj49811nkr9f41n9l1msvmsrmg.png-4.7kB][48]
  4.8 os.listdir
  ![image_1c0bj431l1tdrdrsn3nmd4afm3.png-10.8kB][49]
  以列表的方式列出当前目录有哪些内容
  ‘.’表示当前目录
  默认也是列出当前目录
  ![image_1c0bj4oat1ff79bj1fd81fnavp6mt.png-2.6kB][50]
  列出指定目录内容
  4.9 os.remove
  删除指定内容
  4.10 os.rename
  os.rename('oldname','newname')  重命名
  4.11 os.stat
  获取指定内容属性信息
  ![image_1c0bj5ht865hct4ldhhi216itna.png-9kB][51]
  4.12 os.sep
  在Windows中路径是用 右斜杠\ 来表示分隔的
  在linux中路径是用左斜杠/来表示分隔
  ![image_1c0bj5sd11s1o38b1nmg1pr3i4nn.png-18.6kB][52]
  os.sep会根据系统的不同,来改变分隔符的,在Windows中是\(其中一个\是转译符),使用os.sep代替\,这样即使在不同的操作系统也能正确的使用对应的分隔符
  4.13 os.linesep
  ![image_1c0bj67giohb36b71s13ad1j6po4.png-1.7kB][53]
  换行符是\r\n
  4.14 os.environ与os.pathsep
  ![image_1c0bj6ivthkr1io7106r1fj2vtoh.png-71.6kB][54]
  通过environ获取系统的环境变量,以字典格式显示,在Windows中 如果一个key对应多个路径的话是以分好‘;’分隔的,os.pathsep就是对应这个分隔符(在Windows中对应‘;’,在linux中对应‘:’)
  ![image_1c0bj6uhrr4vhhh1b7fjf15a5ou.png-1.8kB][55]
  4.15 os.name
  ![image_1c0bj8q52kj31hgh7j6aii18sopb.png-1.5kB][56]
  显示当前系统类型,nt表示Windows
  4.16 os.system
  用来执行当前系统的命令
  ![image_1c0bj96gs7pf19q535813hk1720po.png-44.2kB][57]
  编码不同,所以显示乱码
  4.17 os.path
  4.17.1 os.path.abspath
  获取绝对路径(之前在导入模块时使用过,导入不同目录的模块)
  4.17.2 os.path.split
  ![image_1c0bjac20lmcubf17sj1p4hjl2q5.png-4.2kB][58]
  以元组的方式显示,将目录和文件分隔开。
  4.17.3 os.path.dirname与os.path.basename
  ![image_1c0bjaqd1aaplif1eqh7q1unkqi.png-10kB][59]
  一个取目录名,一个结尾的。
  4.17.4 os.path.exist
  ![image_1c0bjbbhm1rp1g5b1ja31n811eqjqv.png-2.6kB][60]
  判断路径是否存在
  4.17.5 os.path.isabs
  ![image_1c0bjce57l1b27a1ptj1ieatnors.png-2.8kB][61]
  判断是否是以根开头的绝对路径
  在Windows中每个盘符都是根,在linux中/是根
  如果False的话就是相对路径
  4.17.6 os.path.isfile与 os.path.isdir
  ![image_1c0bjet2f14qbkr416vb17io12p2s9.png-5.7kB][62]
  判断是否是一个文件
  ![image_1c0bjf7g71tr21746s0h1u2t12pnsm.png-2.8kB][63]
  判断是否是目录
  4.17.7 os.path.join
  ![image_1c0bjgf4j1q7eu04c1r1v2uu0lt3.png-4.3kB][64]
  将目录与文件组合并返回
  4.17.8 os.path.getatime与 os.path.getmtime
  ![image_1c0bjguheji37n6g2r1m07594tg.png-6.9kB][65]
  获取文件的最后存取时间,时间格式为时间戳
  ![image_1c0bjha236ln1ckt1ups1kqoqqstt.png-6.9kB][66]
  获取修改时间

5. sys与shutil模块
  sys模块没有细讲,请单独翻阅资料
  5.1 sys.version
  ![image_1c0bji91j1kg81f69154j10s71nagua.png-8.1kB][67]
  获取当前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][68]
  成功的将test1中的内容copy到test2
  6.2 shutil.copyfile
  shutil.copyfile中已经带有打开文件的代码,所以无需额外再次打开文件了,直接使用即可
  ![image_1c0bjn1en19mb1dtg10fh1rgm1et1vk.png-4.4kB][69]
  ![image_1c0bjn7at9mg1hkm1aceb0k15pt101.png-7.3kB][70]
  6.3 shutil.copymode
  将文件的权限拷贝,新文件的用户属主是新用户
  6.4 shutil.copystat
  ![image_1c0bjnjkf57o1nu2vce14jitl10e.png-4.1kB][71]
  只copy了权限
  6.5 shutil.copytree与shutil.rmtree
  ![image_1c0bjo3dgsa21lqq12i21bsq1v5210r.png-19.2kB][72]
  ![image_1c0bjo8tr1t61v3ni3o5ee1hjj118.png-20.4kB][73]
  6.6 shutil.make_arvhive
  ![image_1c0bjoiqr1fgcc48flo15mo1sgg11l.png-3.5kB][74]
  ![image_1c0bjp4qm1dkr1qfks8kjnl2j2122.png-19.9kB][75]
  默认在当前操作目录
  ![image_1c0bjpfd5asvrjb1j8joh188h12f.png-6.8kB][76]
  ![image_1c0bjpmb812ja17m31buts8hqtg12s.png-2.1kB][77]
  指定目录
  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][78]
  这是一个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][79]
  将第一行的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][80]
  ![image_1c0bk31imjaqi9k20enh8pr714g.png-14.7kB][81]
  child.tag是xml文件中的标签名(如:country), child.attrib是属性(如:name=&quot;Liechtenstein&quot;)
  ![image_1c0bk3g9sssm1v2l4601tvb50314t.png-3.2kB][82]
  

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][83]
  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][84]
  可以看到源文件中的year值都加了一年
  8.3 删除
  ![image_1c0bk5omclpk1gdo1qrq1h5lf16k.png-37.1kB][85]
  删除之前有一个叫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][86]
  已经看不到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][87]
  可以看到生成的xml文件,只不过默认格式不对,需要手动调整一下。
  ![image_1c0bk91cmoa41peh4g1n8p7aj18e.png-34.4kB][88]
  调整后的文件

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][89]
  通过python生成的一个配置文件
  红色表示节点,图中内容有三个节点
  9.2.2 读取
  

import configparser  

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

  
print(conf.defaults())
  

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

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

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

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

  ![image_1c0bkd6vlfq01pebk4v18vnmlt1av.png-14.1kB][92]

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][93]
  第一个生成的MD5是Hello
  第二个生成的MD5是Hello加上Its me
  因为MD5值不能翻转,所以通过其他方式确认第二个MD5是否是两个字符串加在一起生成的
  ![image_1c0bke7bg1u7r1r6t1fv21hlj1jh11bp.png-20.3kB][94]
  ![image_1c0bkepk356oc721kmo1di115it1c6.png-4.7kB][95]
  可以看到通过m2打印的MD5 值与之前的一样,说明之前的解释没有错。
  10.2 sha
  

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

  ![image_1c0bkfkun1anc10kljrq19io1pgq1cj.png-15.2kB][96]
  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][97]
  ![image_1c0bkg9efd92t111umb1asp79b1dd.png-13.3kB][98]
  ![image_1c0bkgeo816sl1hp2jenspbkv41dq.png-13.5kB][99]
  默认不能用中文,只能用ASCII码(前面有b,必须生成bytes格式,bytes格式要用ASCII)
  ![image_1c0bkgsljgjv127ntjd1lk3pac1e7.png-11.9kB][100]
  key必须使用bytes格式,消息可以使用中文,但需要将前面的b去掉,然后并封装新的格式(utf-8)
  ![image_1c0bkh7i3t251lccs4i11bsohv1ek.png-2.8kB][101]

11. subprodcess
  subprodcess是os.system和os.spawn*的替代模块

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][102]
  

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

  这条代码一定要放在下面代码的上面才会生效。
  这里日志级别是DEBUG,意思就是将DEBUG以及比其高的级别的日志都进行输出
  ![image_1c0bkithj173f3g1up9q1a10p51fe.png-8.7kB][103]
  可以看到新增代码后,就不在pycharm中输出日志信息了
  ![image_1c0bkl9qgk8b1ua1aon5jk13791fr.png-28.5kB][104]
  根据指定的app.log文件,将信息输出到文件中。
  ![image_1c0bkm4gf19dk1h1c1hncdr0gfq1g8.png-43kB][105]
  在执行一遍代码,日志信息就会增加到app.log文件中(不会覆盖)
  ![image_1c0bkmfto1o8tnj1lm61l1r13jf1gl.png-26kB][106]
  将WARNING级别以及比其高的级别日志信息输出
  ![image_1c0bkmpdn1bf7e1m6oc1tkuue21h2.png-12.1kB][107]
  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][108]
  ![image_1c0bkrbqa85l1fgp1l1a866sri1k9.png-42.9kB][109]
  ![image_1c0bkr6gptgcde569016kas521js.png-15.7kB][110]
  定义日志格式,让其显示日志级别
  ![image_1c0bkrjeb1gjsni19bt147i1pvg1km.png-12.4kB][111]
  ![image_1c0bkrqmc12861usn1k81180icta1l3.png-16.4kB][112]
  显示输出的文件名
  ![image_1c0bks4ih1o511rvi1ihl1q9mtq31lg.png-28.6kB][113]
  因为格式原因输出有乱码,实际输出的应该是logging模块.py
  ![image_1c0bkshlk18rvi6n12ea1iq45901lt.png-16.9kB][114]
  使用%(lineno)d可以显示输出文档的行号
  ![image_1c0bkssbuj2p19hhajt17be2r21ma.png-17.5kB][115]
  可以看到该日志信息是通过哪个文档的哪一行输出的。
  ![image_1c0bkt6lduufgsr1lon3n9maa1mn.png-17kB][116]
  %(funcName)s显示生成日志的函数名称
  ![image_1c0bktgim1iodlkj1786umi18us1n4.png-7.8kB][117]
  ![image_1c0bktoukd4sj751dmu18npjqd1nh.png-26.4kB][118]
  可以看到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][119]
  输出到屏幕的告警信息,因为定义的最低告警级别是warning,所以两个级别的信息都可以看到
  ![image_1c0bl4fl5ab7l2u801vloam71qo.png-10.8kB][120]
  输出到文件的告警信息,因为定义的级别是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][121]
  可以看到自动截断,只保留了3个备份文件,当前主文件的内容就是最后存储的信息'test6'
  ![image_1c0bl5m6nmvp1stm1mve7du1u151ri.png-12.5kB][122]
  log.1是最接近主文件的内容的,所以是'test5'
  ![image_1c0bl638t1274b47u0ov7uihe1rv.png-13kB][123]
  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][124]
  从第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][125]
  第一个结果可以看到从起始位置匹配到了'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][126]
  13.3 正则表达式修饰符 - 可选标志
  正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
  ![image_1c0bl9vv9nsojf1r7h5og12gf1tj.png-24.7kB][127]
  13.4 正则表达式模式
  模式字符串使用特殊的语法来表示一个正则表达式:
  字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。
  多数字母和数字前加一个反斜杠时会拥有不同的含义。
  标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
  反斜杠本身需要使用反斜杠转义。
  由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'/t',等价于'//t')匹配相应的特殊字符。
  下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。
  ![image_1c0blaf8qeve1rl51vuf3871ib21u0.png-57.1kB][128]
  ![image_1c0blatem1mfg1c0s1lja153c1jui1ud.png-58.4kB][129]
  ![image_1c0blb49d1dfo2tm1vi31n3f17gi1uq.png-22.9kB][130]
  13.5 正则表达式实例
  ![image_1c0blbpa6nmv9q0tsp12nn19rn1v7.png-32.6kB][131]
  ![image_1c0blc05bg5svc7chv1ssq73c1vk.png-31.7kB][132]
  13.6 使用模式举例


  • 使用:'.'
  

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

  ![image_1c0bldjoj1qic1i6375d1lsh154v21h.png-4.3kB][133]
  使用一个'.'表达除了\n 外的任意一个字符(字母、数字、特殊字符),可以看到职匹配了第一个w
  不使用group来表达的话会多现实一些参数,比如span表达了第一个w所在下标的位置范围


  • 使用:'.+'
  

line = 'www.google.com'  

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

  ![image_1c0blducmgd8qa217mp1ul01on021u.png-1.4kB][134]
  '.+'通过'+'匹配了0个或多个'.'


  • 使用:'w','w+'
  

rule1 = re.match(r'w',line)    #匹配一个字母  
rule2 = re.match(r'w+',line)    #匹配0或多个字母
  
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][135]
  匹配了字母,遇见'.'后不符合表达式(不属于字母),所以连带'.'后面的所有内容也都不匹配了。
  

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

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


  • 使用:‘search’
  

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

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

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


  • 使用:‘d’
  

re.search('(\d{3})(\d{4})','123456789123456789').groups()  

  ![image_1c0blgqhrmmc1pci1s13hl0mmh23i.png-6.3kB][138]
  匹配数字,因为有两个(),所以在元组中分为两个元素显示
  使用:‘^,$,Z’
  ![image_1c0blhhnd5j2194s1bst1lpc1st523v.png-19kB][139]
  通过^匹配以数字开头的,通过$匹配以数字结尾的,第一个报错是因为匹配的内容不是数字结尾,另一个匹配则是以数字为结尾所以不会报错。
  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][140]
  

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

  ![image_1c0blm0mddub11jg1ef6c1u1oe824p.png-1.2kB][141]
  

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][142]
  以上都不是合法的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][143]
  

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


  • 使用:'re.findall'
  

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

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

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

  
print (rule3)
  

  ![image_1c0blpcfad3o12ct7f51722e4l26q.png-1.6kB][146]
  \D表示非数字


  •   使用:'re.split'
      

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

      ![image_1c0blq4o0b293161a42fd11bs9277.png-2.1kB][147]

  • 使用re.split分隔成列表显示
  可以看到与findall类似,但是split后面因为有数字所以就分隔了一个空
  

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

  ![image_1c0blqv1h15uljmv3q1m8og7s27k.png-1.7kB][148]
  使用re.split分隔成列表显示
  可以看到与findall类似,但是split后面因为有数字所以就分隔了一个空
  

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

  ![image_1c0blrqj61c51cps1omd1lkr7bd281.png-1.7kB][149]
  会将dd进行分隔


  • 使用:re.sub
  

rule = re.sub('\d+','|','ab13aa22cc334bb44adsf234656dd')  
print (rule)
  

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

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

  ![image_1c0bltm7d13on5bc1ou627o1q9p28r.png-2.4kB][151]
  count是替换几次


  • flags  

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

      ![image_1c0bm05dg16056fl15c7c961arm2b8.png-0.3kB][152]
      只能匹配到小写的a

  

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

  ![image_1c0bm0026igglte16si1n6q1sn52ar.png-0.5kB][153]
  使用falgs中的re.I可以忽略大小写

14.subprocess
DSC0000.jpg

  

    os.system('dir') #可以显示当前目录内容  

  aaa = os.system('dir')   #赋值变量
  

DSC0001.jpg

  打印变量发现得到的不是执行结果,而是执行状态,在Windows中 0 表示执行成功, 1 表示执行失败。
  

    os.popen('dir')    

DSC0002.jpg

  使用os.popen('dir')  可以显示执行结果,但是当前看到的是内存地址
  

    os.popen('dir').read()  

DSC0003.jpg

  需要加一个.read()来查看命令的执行结果


  • subprocess for linux(Ubuntu)
  在linux中尝试使用subprocess模块
DSC0004.jpg

  查看当前路径目录内容,并返回查看信息
  subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn、os.popen、commands.*等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

常用方法:


  • subprocess.call()
  •   subprocess.call(command) 方法
      subprocess的call方法可以用于执行一个外部命令,但该方法不能返回执行的结果,只能返回执行的状态码: 成功(0) 或 错误(非0)
      call()方法中的command可以是一个列表,也可以是一个字符串,作为字符串时需要用原生的shell来执行:

  

import subprocess  

  
#方法一
  
>>> a = subprocess.call(['ls','-l'])
  
总用量 32
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 公共的
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 模板
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 视频
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 图片
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 文档
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 下载
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 音乐
  
drwxr-xr-x 3 test test 4096 12月  3 12:25 桌面
  
>>>
  
>>> a
  
0
  

  
#方法二
  
>>> b = subprocess.call("ls -l",shell=True)
  
总用量 32
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 公共的
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 模板
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 视频
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 图片
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 文档
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 下载
  
drwxr-xr-x 2 test test 4096 12月  3 00:58 音乐
  
drwxr-xr-x 3 test test 4096 12月  3 12:25 桌面
  
>>> b
  
0
  

  如上实例所示,虽然我们能看到执行的结果,但实际获取的值只是状态码
  当调取变量时只能看到0这个状态值


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

>>> a = subprocess.check_call('df -hT',shell=True)  
文件系统       类型      容量  已用  可用 已用% 挂载点
  
udev           devtmpfs  969M     0  969M    0% /dev
  
tmpfs          tmpfs     199M  6.3M  193M    4% /run
  
/dev/sda1      ext4       19G  5.1G   13G   29% /
  
tmpfs          tmpfs     992M  168K  992M    1% /dev/shm
  
tmpfs          tmpfs     5.0M     0  5.0M    0% /run/lock
  
tmpfs          tmpfs     992M     0  992M    0% /sys/fs/cgroup
  
tmpfs          tmpfs     199M   40K  199M    1% /run/user/1000
  
/dev/sr0       iso9660   1.5G  1.5G     0  100% /media/test/Ubuntu-Kylin 16.04 LTS amd64
  
>>>
  
>>> a
  
0
  
>>>
  

  
>>>
  

>>>  
>>> a = subprocess.check_call('dfdsf',shell=True)
  
/bin/sh: 1: dfdsf: not found
  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/subprocess.py", line 581, in check_call
  raise CalledProcessError(retcode, cmd)
  
subprocess.CalledProcessError: Command 'dfdsf' returned non-zero exit status 127
  
>>>
  
>>> a
  
0
  
>>>
  

  


  • subprocess.check_output()
  call()方法启动的进程,其标准输入输出会绑定到父进程的输入和输出。调用程序无法获取命令的输出结果。但可以通过check_output()方法来捕获输出。
  

>>>  
>>> output=subprocess.check_output("ls -l",shell=True)
  
>>>
  
>>> output
  
b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 32\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x 2 test test 4096 12\xe6\x9c\x88  3 00:58 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x 3 test test 4096 12\xe6\x9c\x88  3 12:25 \xe6\xa1\x8c\xe9\x9d\xa2\n'
  
>>>
  
#在python3中输出的结果是bytes格式
  

  以下例子将chek_output()方法执行命令异常时的错误捕获,而避免输出到控制台.
  

>>>  
>>> try:
  
... output = subprocess.check_output("lT -l", shell=True, stderr=subprocess.STDOUT)
  File "<stdin>", line 2
  output = subprocess.check_output("lT -l", shell=True, stderr=subprocess.STDOUT)
  ^
  
IndentationError: expected an indented block
  
>>> try:
  
...     output = subprocess.check_output("lT -l", shell=True, stderr=subprocess.STDOUT)
  
... except subprocess.CalledProcessError as err:
  
...     print("Command Error", err)
  
...
  
Command Error Command 'lT -l' returned non-zero exit status 127
  
>>>
  


  • getstatusoutput
  

>>> a = subprocess.getstatusoutput('ls -l')  
>>>
  
>>> a
  
(0, '总用量 32\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 公共的\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 模板\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 视频\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 图片\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 文档\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 下载\ndrwxr-xr-x 2 test test 4096 12月  3 00:58 音乐\ndrwxr-xr-x 3 test test 4096 12月  3 12:25 桌面')
  
>>>
  
# 直接返回执行状态和结果,通常getstatusoutput使用比其他方式多。
  

  上面这些subprocess的方法底层都是封装的subprocess.Popen


  • subprocess.Popen  

      
    >>> res = subprocess.Popen('ifconfig | grep 192', shell=True)
      
    >>>           inet 地址:192.168.142.128  广播:192.168.142.255  掩码:255.255.255.0

  >> res   #内存地址
  <subprocess.Popen object at 0x7f4b6176a518>
  >>
  >> res.read()  #可以看到使用read读取不到内容
  Traceback (most recent call last):
  File &quot;<stdin>&quot;, line 1, in <module>
  AttributeError: 'Popen' object has no attribute 'read'
  >>
  >>
  

  

  

>>>  
>>> res = subprocess.Popen('ifconfig | grep 192', shell=True,stdout=subprocess.PIPE)    #通过在内存中生成一个管道,将res存储的数据放入管道中,然后通过管道将数据输出到屏幕上。
  
>>> res
  
<subprocess.Popen object at 0x7f4b6176aba8>
  
>>>
  
>>> res.stdout.read()
  
b'          inet \xe5\x9c\xb0\xe5\x9d\x80:192.168.142.128  \xe5\xb9\xbf\xe6\x92\xad:192.168.142.255  \xe6\x8e\xa9\xe7\xa0\x81:255.255.255.0\n'
  
>>>
  
>>>
  

  

  stdout表示标准输出
  stdin表示标准输入
  stderr表示错误
  

>>>  
>>> res = subprocess.Popen('asdf | grep 192', shell=True,stdout=subprocess.PIPE)
  
>>> /bin/sh: 1: asdf: not found
  

  
>>> res.stdout.read()  #错误是没办法直接被输出读取到的
  
b''
  
>>>
  

>>> res = subprocess.Popen('asdf | grep 192', shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)  
>>> res.stdout.read()
  
b''
  
>>>
  
>>> res.stderr.read()   #可以查看错误信息
  
b'/bin/sh: 1: asdf: not found\n'
  
>>>
  
>>>
  

  

  在linux中subprocess每一次执行相当于调用一次shell脚本,而shell相当于一个程序。
  

>>> res = subprocess.Popen("sleep 10; echo 'hello' ", shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)  
>>>
  
>>> res.stdout.read()  #可以看到我们将hello读取出来了,但是在正常执行程序时,这个程序是多久执行完成的我们并不知道。
  
b'hello\n'
  
>>>
  
>>> res = subprocess.Popen("sleep 10; echo 'hello' ", shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)  #我们再次执行该代码
  
>>> res.stdout.read()  #可以发现=需要等待设定的10秒时间,才能将hello输出到屏幕。
  
b'hello\n'
  

  如果使用res.poll()就可以发现当前程序是否执行完成或未完成。
  

>>> res = subprocess.Popen("sleep 10; echo 'hello' ", shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)   #再次执行该程序,需要运行10秒才能完成  

  
>>> print (res.poll())
  
None
  
>>>
  
>>> print (res.poll())
  
None
  
>>>
  
>>> print (res.poll())
  
None
  
>>>
  
>>> print (res.poll())
  
0
  
>>>
  
# 然后我们看到不断的通过print (res.poll()) 查看执行情况,在10秒以内我们可以看到None,说明该程序还未执行完成(但可以确认程序正在执行),直到看到 0 时说明程序已经执行完成
  

  

>>>  
>>> res = subprocess.Popen("sleep 10; echo 'hello' ", shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
  
>>> res.wait()    #wait()直接等待程序执行结果
  
0
  
>>>
  

  

>>> res = subprocess.Popen("sleep 10; echo 'hello' ", shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)  
>>> res.terminate()   #终止程序运行
  
>>>
  
>>> res.stdout.read()   #可以看到没有读取到任何信息,说明程序被终止成功。
  
b''
  
>>>
  

  sub.community  这个功能几乎用不到
  

>>>  
>>> res = subprocess.Popen("pwd ", shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,cwd="/tmp")  #使用cwd可以改变当前程序运行的目录位置
  
>>> res.stdout.read()
  
b'/tmp\n'   #可以看到已经改变位置在/tmp下
  
>>>
  

  可用参数:
  

    args:shell命令,可以是字符串或者序列类型(如:list,元组)  bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
  stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
  close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
  所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
  shell:同上
  cwd:用于设置子进程的当前目录
  env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
  universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
  startupinfo与createionflags只在windows下有效
  将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
  

DSC0005.jpg

  在linux中安装程序需要密码
DSC0006.jpg

  通过这种方式可以实现在linux中自动发送密码
  在python中可以通过subprocess模块发送命令安装
  

  
>>>
  
>>> import subprocess
  
>>>
  
>>> subprocess.Popen("echo '123' | sudo -S apt-get install vim",shell=True)
  
<subprocess.Popen object at 0x7f7f6496e080>
  
正在读取软件包列表... 完成
  
正在分析软件包的依赖关系树
  
正在读取状态信息... 完成
  
将会同时安装下列软件:
  vim-common vim-runtime vim-tiny
  
建议安装:
  ctags vim-doc vim-scripts vim-gnome-py2 | vim-gtk-py2 | vim-gtk3-py2 | vim-athena-py2 | vim-nox-py2 indent
  
下列【新】软件包将被安装:
  vim vim-runtime
  
下列软件包将被升级:
  vim-common vim-tiny
  
升级了 2 个软件包,新安装了 2 个软件包,要卸载 0 个软件包,有 650 个软件包未被升级。
  
需要下载 6,199 kB/6,748 kB 的归档。
  
解压缩后会消耗 30.0 MB 的额外空间。
  
您希望继续执行吗? [Y/n] 中止。
  

  
>>>
  
···
  

  [1]: http://static.zybuluo.com/aubreyzheng/ey3jffkdmvhzy7eim3nlnwca/image_1c0bi1c1j1pkr1rn91ovspjf1omo9.png
  [2]: http://static.zybuluo.com/aubreyzheng/hhm8t6ds9tqms9lysj90e57y/image_1c0bi20qd1hi61lm35m416qd5e7m.png
  [3]: http://static.zybuluo.com/aubreyzheng/s8oz8lcpq08j3war4a7k51jh/image_1c0bi2huj107sqhj1vej9ifle713.png
  [4]: http://static.zybuluo.com/aubreyzheng/muzxad6n6evn7hg9vjwh5tfn/image_1c0bi30g51bnvevd1391asr7ug1g.png
  [5]: http://static.zybuluo.com/aubreyzheng/k09g91hc0fb7t1oz2tykblt2/image_1c0bi3mtd4ki1rgt12fvhoka4e1t.png
  [6]: http://static.zybuluo.com/aubreyzheng/kdsnz5u4kluxa385avsqrrrg/image_1c0bi434g1v2n1aprg9kqrk1te72a.png
  [7]: http://static.zybuluo.com/aubreyzheng/6cwb59jgtwi8w329er97ncrf/image_1c0bi5qjai2j1ken227chthjt3h.png
  [8]: http://static.zybuluo.com/aubreyzheng/mvm4teauy1n906le1lt4f72t/image_1c0bi688v11i51g2c1l051srqupe3u.png
  [9]: http://static.zybuluo.com/aubreyzheng/h6cwt2jtowmi2e5fm680h6g2/image_1c0bi6hjnh7a1v11ut31ul1gmm4b.png
  [10]: http://static.zybuluo.com/aubreyzheng/4u7u5znuno2a42hig4tbynao/image_1c0bi7328c3qj6n8h69bo1snk4o.png
  [11]: http://static.zybuluo.com/aubreyzheng/d6feq80k196tuu854g09rz0u/image_1c0bi7ig9t5f9pp144o1f0p5nj55.png
  [12]: http://static.zybuluo.com/aubreyzheng/2mqgou980vbnyyro8i1mau60/image_1c0bi7vd21ov0uisg5714rc1shg5i.png
  [13]: http://static.zybuluo.com/aubreyzheng/04r8yk5j76jhlwty4aryzfkw/image_1c0bi8ktmssm1r8jtj4u1hasv5v.png
  [14]: http://static.zybuluo.com/aubreyzheng/frxw3vqxdpojqmtwzxcok061/image_1c0bi9cgi81eu0q1g05hsubln6c.png
  [15]: http://static.zybuluo.com/aubreyzheng/09z1ovayiwxrwl1y6envf5o2/image_1c0bi9udvbi1l0ikkf1jea1fs16p.png
  [16]: http://static.zybuluo.com/aubreyzheng/r62hajzf8xh26wzg2kz7ip6w/image_1c0bia92f9cg17kj19fchbliiq76.png
  [17]: http://static.zybuluo.com/aubreyzheng/62lybvxuqcn8qky326w532z7/image_1c0bianj0dedhi214cm1r1lqq17j.png
  [18]: http://static.zybuluo.com/aubreyzheng/vt3nc27fdxnn95d9irdgfbqi/image_1c0bias9n1l9974h9njdi6106a80.png
  [19]: http://static.zybuluo.com/aubreyzheng/fl7lou3rgxhdxlwwf59aw2aq/image_1c0bib8gnbuv17er2dji2oa3r8d.png
  [20]: http://static.zybuluo.com/aubreyzheng/ugi8m8ht4ve2sgey2n0yky9w/image_1c0bibknfqd91ojs17671eh1k7f8q.png
  [21]: http://static.zybuluo.com/aubreyzheng/td03i1l1abior0y37f32hx2y/image_1c0bici7tr8jotq6is15nn1def97.png
  [22]: http://static.zybuluo.com/aubreyzheng/kqhd595c9285otrdft1sk5z3/image_1c0bics6ehj5567qn0cfn7s99k.png
  [23]: http://static.zybuluo.com/aubreyzheng/9xbj46xvrvbfo06ipu3derfd/image_1c0bidam5djm1mh0125r7irm95a1.png
  [24]: http://static.zybuluo.com/aubreyzheng/5aagf90xuptqst0vjcymycuo/image_1c0bidt661st9ltc1tng6dbkuoae1.png
  [25]: http://static.zybuluo.com/aubreyzheng/cb4n66w385dgf20tov4xgl48/image_1c0bieb2um9uquv1cmc1vu2q7qar.png
  [26]: http://static.zybuluo.com/aubreyzheng/6ggapqsa9jdx5n7amfyzgigj/image_1c0bien86ad11rh9021n8scnb8.png
  [27]: http://static.zybuluo.com/aubreyzheng/6r3xnlwm48ddeqzy3y2ttk5v/image_1c0bif49i1g9goma1ovhe9912kbl.png
  [28]: http://static.zybuluo.com/aubreyzheng/a0r3bwqub6ijxyh68g095tv1/image_1c0big5tn14abk9j1vf2fv01u0oc2.png
  [29]: http://static.zybuluo.com/aubreyzheng/8a3ve4cw17n2ktizhs1loz2t/image_1c0bigmvoepf10roneo11nq1etacf.png
  [30]: http://static.zybuluo.com/aubreyzheng/if0hr28ye1d5eyzgqye5hbq4/image_1c0bihqs5131lh910gk1nfgpqmcs.png
  [31]: http://static.zybuluo.com/aubreyzheng/q0u5c5uocegi325o8gf0iws0/image_1c0bijapt16v2ej91ug01gju14aod9.png
  [32]: http://static.zybuluo.com/aubreyzheng/fyzzrugu3umqj5w02iq2v1oj/image_1c0bijkuqskr17tshu3036lodm.png
  [33]: http://static.zybuluo.com/aubreyzheng/fffu6uq6a4m4334x53k6vchw/image_1c0bikp1po7q13hh1o191t994dne3.png
  [34]: http://static.zybuluo.com/aubreyzheng/mtb6alju24ibr2hn0xd5zb4c/image_1c0bilu6c1cgiu351k6h7dra9eg.png
  [35]: http://static.zybuluo.com/aubreyzheng/2w72cp7x4040mc2pkoop211w/image_1c0bimdeb1d2s1j2t1dg21u8k1tonet.png
  [36]: http://static.zybuluo.com/aubreyzheng/cenoiys05zqvrukkteei3lm7/image_1c0bin1jl1hmpcaf571vqipunfa.png
  [37]: http://static.zybuluo.com/aubreyzheng/5vj7riklw3qc5ub1s55zvsuo/image_1c0binjejnbenno1e231nqnek1fn.png
  [38]: http://static.zybuluo.com/aubreyzheng/ao37cwic752r5zn9sveeuect/image_1c0bip3fam0a1pu819kl1m1npf3g4.png
  [39]: http://static.zybuluo.com/aubreyzheng/ifeo1nuer3t35qw7034tuabg/image_1c0bipq7lc3d1brj1olr18c1cc8gh.png
  [40]: http://static.zybuluo.com/aubreyzheng/7vol4du4k9tfbtmerglnrjsh/image_1c0biq44ifjr1ffe1v2oqt8h1gu.png
  [41]: http://static.zybuluo.com/aubreyzheng/pjj12wnscnmiro99mph24o67/image_1c0bisl0f1v4p1o1sjdk1m881j9thr.png
  [42]: http://static.zybuluo.com/aubreyzheng/ioltyz76ybqafbz0udoi06tm/image_1c0bitgst1aav7121lt2ge71q6kil.png
  [43]: http://static.zybuluo.com/aubreyzheng/jwwcthv32496awe0vyxj9g11/image_1c0bitle91v3i73g7ckdbafgtj2.png
  [44]: http://static.zybuluo.com/aubreyzheng/51ih3p70nhon8wptnsq4vs0i/image_1c0bj1gu11a331ou15teheq1r4tjf.png
  [45]: http://static.zybuluo.com/aubreyzheng/spshrdh070rlvi8767bu2da9/image_1c0bj1r2mditgbv1rc63063vdjs.png
  [46]: http://static.zybuluo.com/aubreyzheng/cf4o5459tdkt203vwtbxjpbs/image_1c0bj1vtteng7qrqqgire16m9k9.png
  [47]: http://static.zybuluo.com/aubreyzheng/182hadpvpmh6jnv3zd14ji7u/image_1c0bj2iv61dfc2u57lj9h75pkkm.png
  [48]: http://static.zybuluo.com/aubreyzheng/d6ihdp2r6j86e1r9u0we3w8p/image_1c0bj49811nkr9f41n9l1msvmsrmg.png
  [49]: http://static.zybuluo.com/aubreyzheng/lcokg4ptzkvvvlajqw60tdhf/image_1c0bj431l1tdrdrsn3nmd4afm3.png
  [50]: http://static.zybuluo.com/aubreyzheng/n702i2lgx5jlk8dr8x1h3907/image_1c0bj4oat1ff79bj1fd81fnavp6mt.png
  [51]: http://static.zybuluo.com/aubreyzheng/iomnlloao7lotn6794kcvpic/image_1c0bj5ht865hct4ldhhi216itna.png
  [52]: http://static.zybuluo.com/aubreyzheng/anfqcfnxteyf7x4fcganot1y/image_1c0bj5sd11s1o38b1nmg1pr3i4nn.png
  [53]: http://static.zybuluo.com/aubreyzheng/wh6off1jy40ejnqdf0ytsp8r/image_1c0bj67giohb36b71s13ad1j6po4.png
  [54]: http://static.zybuluo.com/aubreyzheng/b02611prwrby38mbobj8c0yl/image_1c0bj6ivthkr1io7106r1fj2vtoh.png
  [55]: http://static.zybuluo.com/aubreyzheng/wazpjygag4zpps7u0vy7fnd3/image_1c0bj6uhrr4vhhh1b7fjf15a5ou.png
  [56]: http://static.zybuluo.com/aubreyzheng/cc0ncu5fbpzmxzwcg58k63lf/image_1c0bj8q52kj31hgh7j6aii18sopb.png
  [57]: http://static.zybuluo.com/aubreyzheng/ji47st72indkdt17sihfdfz0/image_1c0bj96gs7pf19q535813hk1720po.png
  [58]: http://static.zybuluo.com/aubreyzheng/rorcdp0xt60ekucc6r73349p/image_1c0bjac20lmcubf17sj1p4hjl2q5.png
  [59]: http://static.zybuluo.com/aubreyzheng/2a2bxbo566rqm426so6w9tnu/image_1c0bjaqd1aaplif1eqh7q1unkqi.png
  [60]: http://static.zybuluo.com/aubreyzheng/i77f5alssy5sky7tiswlpvm3/image_1c0bjbbhm1rp1g5b1ja31n811eqjqv.png
  [61]: http://static.zybuluo.com/aubreyzheng/9k7tu25cy8cn08ovstct6rif/image_1c0bjce57l1b27a1ptj1ieatnors.png
  [62]: http://static.zybuluo.com/aubreyzheng/9g7p6qxmzebimxl2znuxmsat/image_1c0bjet2f14qbkr416vb17io12p2s9.png
  [63]: http://static.zybuluo.com/aubreyzheng/2y0fo7ciiz2a24291tdsa1ci/image_1c0bjf7g71tr21746s0h1u2t12pnsm.png
  [64]: http://static.zybuluo.com/aubreyzheng/6yosalwe8me7oz9ri0j3gqai/image_1c0bjgf4j1q7eu04c1r1v2uu0lt3.png
  [65]: http://static.zybuluo.com/aubreyzheng/zdb8w0fhurq7p5r73xbnxc8e/image_1c0bjguheji37n6g2r1m07594tg.png
  [66]: http://static.zybuluo.com/aubreyzheng/g46z3g2ga44hf5xdx6bg5kvr/image_1c0bjha236ln1ckt1ups1kqoqqstt.png
  [67]: http://static.zybuluo.com/aubreyzheng/4glkir7nkxlbwo7kb0t0ql2q/image_1c0bji91j1kg81f69154j10s71nagua.png
  [68]: http://static.zybuluo.com/aubreyzheng/1dkkc6byzjbgaa6oald6xdo3/image_1c0bjmetm1v2eg3m10kbsf4qv2v7.png
  [69]: http://static.zybuluo.com/aubreyzheng/ul0uhdmibd4y9yk94577lwk3/image_1c0bjn1en19mb1dtg10fh1rgm1et1vk.png
  [70]: http://static.zybuluo.com/aubreyzheng/2fnvoagglviqkdslmpnsuny8/image_1c0bjn7at9mg1hkm1aceb0k15pt101.png
  [71]: http://static.zybuluo.com/aubreyzheng/9mxo06ikjufrfw90s2yzfguh/image_1c0bjnjkf57o1nu2vce14jitl10e.png
  [72]: http://static.zybuluo.com/aubreyzheng/77nrvmonwibdft458f6guliq/image_1c0bjo3dgsa21lqq12i21bsq1v5210r.png
  [73]: http://static.zybuluo.com/aubreyzheng/qhon57jrxexpmekruk5cy0nt/image_1c0bjo8tr1t61v3ni3o5ee1hjj118.png
  [74]: http://static.zybuluo.com/aubreyzheng/3vucp1d8qnukra8wv0ednfvw/image_1c0bjoiqr1fgcc48flo15mo1sgg11l.png
  [75]: http://static.zybuluo.com/aubreyzheng/kaj13x61oclclj9gxnccb6z4/image_1c0bjp4qm1dkr1qfks8kjnl2j2122.png
  [76]: http://static.zybuluo.com/aubreyzheng/srkppai6qzgcci43x8nan9mx/image_1c0bjpfd5asvrjb1j8joh188h12f.png
  [77]: http://static.zybuluo.com/aubreyzheng/qeb0erxrt1c8ee3ceujek0zv/image_1c0bjpmb812ja17m31buts8hqtg12s.png
  [78]: http://static.zybuluo.com/aubreyzheng/ecuj5yojde6qy10dvjq6bvqf/image_1c0bk16o75am1kb91dnr1gf31mie139.png
  [79]: http://static.zybuluo.com/aubreyzheng/24wwxotvly4nlshcz4aceqq0/image_1c0bk1qviaeq1giv12il1ovu1lsv13m.png
  [80]: http://static.zybuluo.com/aubreyzheng/akw62ujww1m8aod8fwmjf2m2/image_1c0bk2ruq11a21014kkf1dli12cv143.png
  [81]: http://static.zybuluo.com/aubreyzheng/v4392yefguighsb87ucbf2i0/image_1c0bk31imjaqi9k20enh8pr714g.png
  [82]: http://static.zybuluo.com/aubreyzheng/l772n0eanhow3y23t0j91epe/image_1c0bk3g9sssm1v2l4601tvb50314t.png
  [83]: http://static.zybuluo.com/aubreyzheng/sypytsgrymgrfdzegzjb84s9/image_1c0bk4kh21kev18nh8qa1m8d8do15q.png
  [84]: http://static.zybuluo.com/aubreyzheng/u30l7nrfwolqw37ubmqkv6xv/image_1c0bk53bv1kkcic2mu8ukm412167.png
  [85]: http://static.zybuluo.com/aubreyzheng/h5vpq3fmhvwn9ieiyykiimcn/image_1c0bk5omclpk1gdo1qrq1h5lf16k.png
  [86]: http://static.zybuluo.com/aubreyzheng/jxh90gbgz02n11y7nbsqcof2/image_1c0bk67dp15ah11031umb1bvo1tvs171.png
  [87]: http://static.zybuluo.com/aubreyzheng/tcnql7ie5m38nqm72qauyeby/image_1c0bk9b29q2j1fvqi51jtqep818r.png
  [88]: http://static.zybuluo.com/aubreyzheng/6ye6u17aik43y7nuvp0kftic/image_1c0bk91cmoa41peh4g1n8p7aj18e.png
  [89]: http://static.zybuluo.com/aubreyzheng/3fa0hjfz7cdu5e8kxzzgvpu0/image_1c0bkari3boj1m7n1k8k1k5l1ato198.png
  [90]: http://static.zybuluo.com/aubreyzheng/cpzvqhmg0mcscnw9oaiawzil/image_1c0bkc815nst6m1e661a9oe741a5.png
  [91]: http://static.zybuluo.com/aubreyzheng/08p3qwmedotjunoxa8smczmy/image_1c0bkcl3mqjm76t1shv17rfp641ai.png
  [92]: http://static.zybuluo.com/aubreyzheng/pik58kv5be7mrth6178jvsue/image_1c0bkd6vlfq01pebk4v18vnmlt1av.png
  [93]: http://static.zybuluo.com/aubreyzheng/9tkffy7i2ctgmyqcgyi00svf/image_1c0bkds20b5pcj516111e3o10uo1bc.png
  [94]: http://static.zybuluo.com/aubreyzheng/wzdkhf38vzi4x2orycay95bh/image_1c0bke7bg1u7r1r6t1fv21hlj1jh11bp.png
  [95]: http://static.zybuluo.com/aubreyzheng/9jzd99ccin4anc7brc8l09oi/image_1c0bkepk356oc721kmo1di115it1c6.png
  [96]: http://static.zybuluo.com/aubreyzheng/g81znbbe6bqkujcqie7cck6o/image_1c0bkfkun1anc10kljrq19io1pgq1cj.png
  [97]: http://static.zybuluo.com/aubreyzheng/6p2t2xnyeh4qzyzuacxgihku/image_1c0bkg34d1psdvb7ivm2hk1bpt1d0.png
  [98]: http://static.zybuluo.com/aubreyzheng/a1wdk240h5vnazhes7mta65h/image_1c0bkg9efd92t111umb1asp79b1dd.png
  [99]: http://static.zybuluo.com/aubreyzheng/4eakksn7kbhnnq9wxic0doe8/image_1c0bkgeo816sl1hp2jenspbkv41dq.png
  [100]: http://static.zybuluo.com/aubreyzheng/3zn0yi0xfyq3v8712nr9ya1p/image_1c0bkgsljgjv127ntjd1lk3pac1e7.png
  [101]: http://static.zybuluo.com/aubreyzheng/425j9z54d150m8aa0cbtsvj4/image_1c0bkh7i3t251lccs4i11bsohv1ek.png
  [102]: http://static.zybuluo.com/aubreyzheng/yhdm313y3bk8l7yqmn80uxy8/image_1c0bki7b07ro17qo1ln5pl91l1a1f1.png
  [103]: http://static.zybuluo.com/aubreyzheng/j0oppgjrdx7vru77v5taecfq/image_1c0bkithj173f3g1up9q1a10p51fe.png
  [104]: http://static.zybuluo.com/aubreyzheng/wxmelxq8rb2paf2vvdbnsofk/image_1c0bkl9qgk8b1ua1aon5jk13791fr.png
  [105]: http://static.zybuluo.com/aubreyzheng/lplbwf33izyixp2pq6jb9pzp/image_1c0bkm4gf19dk1h1c1hncdr0gfq1g8.png
  [106]: http://static.zybuluo.com/aubreyzheng/y2tojmt5efuqci5obcwahfye/image_1c0bkmfto1o8tnj1lm61l1r13jf1gl.png
  [107]: http://static.zybuluo.com/aubreyzheng/abyu9zqidq1pnbeocry9rus8/image_1c0bkmpdn1bf7e1m6oc1tkuue21h2.png
  [108]: http://static.zybuluo.com/aubreyzheng/72gf1iwbnw67w734jtth293i/image_1c0bkoe9f138a1na9chb13ar1b761hf.png
  [109]: http://static.zybuluo.com/aubreyzheng/f6tvgkho7f3s6l1a7cb7ci20/image_1c0bkrbqa85l1fgp1l1a866sri1k9.png
  [110]: http://static.zybuluo.com/aubreyzheng/9s20gvlbd5l7i0xy11jbcxb7/image_1c0bkr6gptgcde569016kas521js.png
  [111]: http://static.zybuluo.com/aubreyzheng/m1po7v0stqang0b9g036waj0/image_1c0bkrjeb1gjsni19bt147i1pvg1km.png
  [112]: http://static.zybuluo.com/aubreyzheng/98104blqgy4bqn9asgenzslq/image_1c0bkrqmc12861usn1k81180icta1l3.png
  [113]: http://static.zybuluo.com/aubreyzheng/dxmekpz7mlhmzrjfl09sqz23/image_1c0bks4ih1o511rvi1ihl1q9mtq31lg.png
  [114]: http://static.zybuluo.com/aubreyzheng/jl7t9j2olo40f7cov4aruz0q/image_1c0bkshlk18rvi6n12ea1iq45901lt.png
  [115]: http://static.zybuluo.com/aubreyzheng/6u9mfb41yrdwt9ptyd2frs1m/image_1c0bkssbuj2p19hhajt17be2r21ma.png
  [116]: http://static.zybuluo.com/aubreyzheng/sq7z9p0aaxb4xcrgnsnza6pc/image_1c0bkt6lduufgsr1lon3n9maa1mn.png
  [117]: http://static.zybuluo.com/aubreyzheng/ni5ume94g1lt696l6pu3db97/image_1c0bktgim1iodlkj1786umi18us1n4.png
  [118]: http://static.zybuluo.com/aubreyzheng/szzrvino4b03au2io5q44z0w/image_1c0bktoukd4sj751dmu18npjqd1nh.png
  [119]: http://static.zybuluo.com/aubreyzheng/mzy90dmmka28k39m94gb2lxe/image_1c0bl46en1i8g5cad4t13r31f821qb.png
  [120]: http://static.zybuluo.com/aubreyzheng/b0v6vin4mck1hhuq45jxqwif/image_1c0bl4fl5ab7l2u801vloam71qo.png
  [121]: http://static.zybuluo.com/aubreyzheng/z42kohkuapcyo7je98qc1ya4/image_1c0bl5cqkr4oshurnh1tr9qgh1r5.png
  [122]: http://static.zybuluo.com/aubreyzheng/mzq2tiuu8n1g6icm9iznbchk/image_1c0bl5m6nmvp1stm1mve7du1u151ri.png
  [123]: http://static.zybuluo.com/aubreyzheng/amlkjdtguagxbaqh63nnkc42/image_1c0bl638t1274b47u0ov7uihe1rv.png
  [124]: http://static.zybuluo.com/aubreyzheng/gtxyxqkjun0764bvvd3np55o/image_1c0bl79c51sc5197p10et1bm619ps1sc.png
  [125]: http://static.zybuluo.com/aubreyzheng/tnjx5pq8hwzjstpkkhfsp3f5/image_1c0bl8htnbsm16lhccj1ado14901sp.png
  [126]: http://static.zybuluo.com/aubreyzheng/or3lur7t0ag87ocwznw7mol5/image_1c0bl9gdj11rt1pn6g0p1pli1ngt1t6.png
  [127]: http://static.zybuluo.com/aubreyzheng/wxu79oa5lssudbh7glangeb2/image_1c0bl9vv9nsojf1r7h5og12gf1tj.png
  [128]: http://static.zybuluo.com/aubreyzheng/5e14hr679co12lu69mkuf8ee/image_1c0blaf8qeve1rl51vuf3871ib21u0.png
  [129]: http://static.zybuluo.com/aubreyzheng/6rnjncjrh1k1i023pyu9nfhd/image_1c0blatem1mfg1c0s1lja153c1jui1ud.png
  [130]: http://static.zybuluo.com/aubreyzheng/8941bkawpocgw2qo9pm95rei/image_1c0blb49d1dfo2tm1vi31n3f17gi1uq.png
  [131]: http://static.zybuluo.com/aubreyzheng/z7itz04crxwcfhkw1bdano5n/image_1c0blbpa6nmv9q0tsp12nn19rn1v7.png
  [132]: http://static.zybuluo.com/aubreyzheng/73r2bln7v5uvg05miq0kwow4/image_1c0blc05bg5svc7chv1ssq73c1vk.png
  [133]: http://static.zybuluo.com/aubreyzheng/5md1ckbxnudwmu7bsewnjl9i/image_1c0bldjoj1qic1i6375d1lsh154v21h.png
  [134]: http://static.zybuluo.com/aubreyzheng/kh8niqgn16ng4n1sezfmomyd/image_1c0blducmgd8qa217mp1ul01on021u.png
  [135]: http://static.zybuluo.com/aubreyzheng/cvsruqhcfqv70q8uid4gsxh7/image_1c0blev5v12ess0ied86rjja722b.png
  [136]: http://static.zybuluo.com/aubreyzheng/klj4zklbf5xnm7zucdfzzbkd/image_1c0blfk381h8s1f5s1vbf1egcvn022o.png
  [137]: http://static.zybuluo.com/aubreyzheng/xdszn23w5s5o6qrbgz27v9ht/image_1c0blg77913urboo1sv3c7c1k40235.png
  [138]: http://static.zybuluo.com/aubreyzheng/ydnfymyamfppic6nic386qsh/image_1c0blgqhrmmc1pci1s13hl0mmh23i.png
  [139]: http://static.zybuluo.com/aubreyzheng/5hem9ntu4epfdyqb5fw1cze6/image_1c0blhhnd5j2194s1bst1lpc1st523v.png
  [140]: http://static.zybuluo.com/aubreyzheng/e059hu6h38j93x7pklf97s3c/image_1c0bllfe512of1k01sa11e14102424c.png
  [141]: http://static.zybuluo.com/aubreyzheng/jk51wragrmsmfto8g8yprepl/image_1c0blm0mddub11jg1ef6c1u1oe824p.png
  [142]: http://static.zybuluo.com/aubreyzheng/w3g9c2c628r3ctnj1vmpvu6v/image_1c0blmmi310n71b951rimoo41pa9256.png
  [143]: http://static.zybuluo.com/aubreyzheng/6r7vlt027t6d7kc3bvg4ve0b/image_1c0blnhr51jo1gd8rj5gld4ll25j.png
  [144]: http://static.zybuluo.com/aubreyzheng/vr16os9gewfc585panvfytuv/image_1c0blo0mka38741h8l1cth65k260.png
  [145]: http://static.zybuluo.com/aubreyzheng/6vrgwx924uiw7gouz9gi4srp/image_1c0blot4i1hku1ng6g9n14p5qem26d.png
  [146]: http://static.zybuluo.com/aubreyzheng/pfc0lclttnaxuszf7quf88ey/image_1c0blpcfad3o12ct7f51722e4l26q.png
  [147]: http://static.zybuluo.com/aubreyzheng/snqkob9t2eqcf2rxkahphmp7/image_1c0blq4o0b293161a42fd11bs9277.png
  [148]: http://static.zybuluo.com/aubreyzheng/25red0rawbg0ay2y3b1nkb8e/image_1c0blqv1h15uljmv3q1m8og7s27k.png
  [149]: http://static.zybuluo.com/aubreyzheng/5y2dqb57q9qbhrloo73orxg8/image_1c0blrqj61c51cps1omd1lkr7bd281.png
  [150]: http://static.zybuluo.com/aubreyzheng/ezlparxosb61exm7eqpnbrje/image_1c0blst921gpudlh6u51mth6gv28e.png
  [151]: http://static.zybuluo.com/aubreyzheng/s847do97hbqct2pn2dzy2yyn/image_1c0bltm7d13on5bc1ou627o1q9p28r.png
  [152]: http://static.zybuluo.com/aubreyzheng/samzeoql2isq5w52utvrrvmm/image_1c0bm05dg16056fl15c7c961arm2b8.png
  [153]: http://static.zybuluo.com/aubreyzheng/7dwgypobxm4hocl0t6rrjfi1/image_1c0bm0026igglte16si1n6q1sn52ar.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-546377-1-1.html 上篇帖子: python数字和字符串对象 下篇帖子: Python学习笔记——1章 python基础
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表