一 time模块(时间模块)★★★★
时间表现形式
在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:
(1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
(2)格式化的时间字符串(Format String): ‘1988-03-16’
(3)元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
import time res=type(time.time()) #我们运行“type(time.time())”,返回的是float类型 print(res) #打印结果 <class 'float'> 时间戳 import time print(time.time()) #返回当前时间的时间戳 从1970年到现在时间的总秒数 #打印结果 1493204066.464622 时间字符串 import time res=time.strftime("%Y-%m-%d %X") #返回当前时间,按年-月-日 时分秒显示,中间的连接符自定义 print(res) #打印结果 2017-04-26 18:54:48 时间元组 import time res=time.localtime() #返回 年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时 print(res) 打印结果 time.struct_time(tm_year=2017, tm_mon=4, tm_mday=26, tm_hour=18, tm_min=55, tm_sec=7, tm_wday=2, tm_yday=116, tm_isdst=0)
小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的
几种时间形式的转换
⑴
式的转换 #1,时间戳<---->结构化时间: localtime/gmtime mktime import time a1=time.localtime(3600*24) a2=time.gmtime(3600*24) print(a1) print(a2) a3=time.mktime(time.localtime()) print(a3) #2,字符串时间<---->结构化时间: strftime/strptime import time a1=time.strftime("%Y-%m-%d %X", time.localtime()) a2=time.strptime("2017-03-16","%Y-%m-%d") print(a1) print(a2
⑵
>>> time.asctime(time.localtime(312343423)) 'Sun Nov 25 10:03:43 1979' >>> time.ctime(312343423) 'Sun Nov 25 10:03:43 1979'
1 #--------------------------其他方法 2 # sleep(secs) 3 # 线程推迟指定的时间运行,单位为秒。
二 random模块(随机数模块)★★
1 >>> import random 2 >>> random.random() # 大于0且小于1之间的小数 3 0.7664338663654585 4 5 >>> random.randint(1,5) # 大于等于1且小于等于5之间的整数 6 7 >>> random.randrange(1,3) # 大于等于1且小于3之间的整数 8 9 >>> random.choice([1,'23',[4,5]]) # #1或者23或者[4,5] 10 11 >>> random.sample([1,'23',[4,5]],2) # #列表元素任意2个组合 12 [[4, 5], '23'] 13 14 >>> random.uniform(1,3) #大于1小于3的小数 15 1.6270147180533838 16 17 >>> item=[1,3,5,7,9] 18 >>> random.shuffle(item) # 打乱次序 19 >>> item 20 [5, 1, 3, 7, 9] 21 >>> random.shuffle(item) 22 >>> item 23 [5, 9, 7, 1, 3]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import random 2 3 def v_code(): 4 5 code = '' 6 for i in range(5): 7 8 num=random.randint(0,9) 9 alf=chr(random.randint(65,90)) 10 add=random.choice([num,alf]) 11 code="".join([code,str(add)]) 12 13 return code 14 15 print(v_code())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #生成验证码2 2 3 def validate(): 4 s="" 5 for i in range(5): 6 rNum=random.randint(0,9) 7 r_alph=chr(random.randint(65,90)) 8 9 ret=random.choice([str(rNum),r_alph]) 10 s+=ret 11 12 return s 13 14 print(val
三 hashlib(摘要算法)★★
算法介绍
Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。
什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。
摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。
我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:
#常见摘要算法 MD5 import hashlib m=hashlib.md5() m.update("alex".encode("utf8")) #534b44a19bf18d20b71ecc4eb77c572f print(m.hexdigest()) m.update("alex".encode("utf8")) #alexalex print(m.hexd
如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:
m.update("alex".encode("utf8")) #alexalex print(m.hexdigest())
MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:
#另一种常见的摘要算法是SHA1 import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in '.encode("utf8")) sha1.update('python hashlib?'.encode("utf8")) print(sha1.hexdigest())
SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。
摘要算法应用
任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:
name | password --------+---------- michael | 123456 bob | abc999 alice | alice2008
如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:
username | password ---------+--------------------------------- michael | e10adc3949ba59abbe56e057f20f883e bob | 878ef96e86145580c38c87f0410ad153 alice | 99b1c2188db85afee403b1536010c2c9
考虑这么个情况,很多用户喜欢用123456,888888,password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:
'e10adc3949ba59abbe56e057f20f883e': '123456' '21218cca77804d2ba1922c33e0151105': '888888' '5f4dcc3b5aa765d61d8327deb882cf99': 'password'
这样,无需破解,只需要对比数据库的MD5,黑客就获得了使用常用口令的用户账号。
对于用户来讲,当然不要使用过于简单的口令。但是,我们能否在程序设计上对简单口令加强保护呢?
由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:
hashlib.md5("salt".encode("utf8"))
经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。
但是如果有两个用户都使用了相同的简单口令比如123456,在数据库中,将存储两条相同的MD5值,这说明这两个用户的口令是一样的。有没有办法让使用相同口令的用户存储不同的MD5呢?
如果假定用户无法修改登录名,就可以通过把登录名作为Salt的一部分来计算MD5,从而实现相同口令的用户也存储不同的MD5。
摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。
四 os模块★★★★
os模块是与操作系统交互的一个接口
''' os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" " os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.environ 获取系统环境变量 os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小 '''
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import os 2 3 print(os.getcwd()) 4 5 f=open("test.txt","w") 6 7 os.chdir(r"C:UsersAdministratorPycharmProjectspy_fullstack_s4day32") # cd 8 9 f=open("test2.txt","w") 10 11 print(os.getcwd()) 12 13 14 os.makedirs("aaaaa/bbb") 15 os.removedirs("aaaaa/bbb") 16 17 print(os.listdir(r"C:UsersAdministratorPycharmProjectspy_fullstack_s4day33")) 18 19 print(os.stat(r"C:UsersAdministratorPycharmProjectspy_fullstack_s4day33 est.txt")) 20 21 22 ''' 23 os.stat_result(st_mode=33206, st_ino=10133099161702379, st_dev=3233102476, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1493176560, st_mtime=1493176614, st_ctime=1493176560) 24 25 ''' 26 27 "yuan"+os.sep+"image" 28 29 print(os.name) 30 print(os.system("dir")) 31 32 abs=os.path.abspath("test.txt") 33 print(os.path.basename(abs)) 34 print(os.path.dirname(abs)) 35 36 s1=r"C:UsersAdministratorPycharmProjects" 37 38 s2=r"py_fullstack_s4day33" 39 40 print(s1+os.sep+s2) 41 42 ret=os.path.join(s1,s2) # 推荐方式 43 print(
五 sys模块★★★
print(sys.argv) #命令行参数List,第一个元素是程序本身路径 print(sys.exit(n)) #退出程序,正常退出时exit(0) print(sys.version) #获取Python解释程序的版本信息 print(sys.maxint) #最大的Int值 print(sys.path) #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 print(sys.platform) #返回操作系统平台名称
六 logging模块(日志模块)★★★★★
函数式简单配置
import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
灵活配置日志级别,日志格式,输出位置:
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/tmp/test.log', filemode='w') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
配置参数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 数字形式的日志级别 %(levelname)s 文本形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息
logger对象配置
import logging logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log') # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')
logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别。
七 re模块(正则表达式)★★★★★
就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
常用正则表达式符号:
'.' 默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE) '$' 匹配字符结尾,或e.search("foo$","bfoo sdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] '?' 匹配前一个字符1次或0次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c 'A' 只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的 '' 匹配字符结尾,同$ 'd' 匹配数字0-9 'D' 匹配非数字 'w' 匹配[A-Za-z0-9] 'W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、 、 、 , re.search("s+","ab c1 3").group() 结果 ' ' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
最常用的匹配语法:
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
re.split 按某种形式分割
re.
compile 建立匹配的规则,可以被调用
详细如下:
import re #1 re.findall('a','alvin yuan') #返回所有满足匹配条件的结果,放在列表里 #2 re.search('a','alvin yuan').group() #函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 #3 re.match('a','abc').group() #同search,不过尽在字符串开始处进行匹配 #4 ret=re.split('[ab]','abcd') #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret)#['', '', 'cd'] #5 ret=re.sub('d','abc','alvin5yuan6',1) print(ret)#alvinabcyuan6 ret=re.subn('d','abc','alvin5yuan6') print(ret)#('alvinabcyuanabc', 2) #6 obj=re.compile('d{3}') ret=obj.search('abc123eeee') print(ret.group())#123
import re ret=re.finditer('d','ds3sy4784a') print(ret) #<callable_iterator object at 0x10195f940> print(next(ret).group()) print(next(ret).group())
注意:
import re ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com') print(ret)#['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com') print(ret)#['www.oldboy.com']
补充:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import re print(re.findall("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>")) print(re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>")) print(re.search(r"<(w+)>w+</1>","<h1>hello</h1>"))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#匹配出所有的整数 import re #ret=re.findall(r"d+{0}]","1-2*(60+(-40.35/5)-(-4*3))") ret=re.findall(r"-?d+.d*|(-?d+)","1-2*(60+(-40.35/5)-(-4*3))") ret.remove("") print(ret)
元字符之转义符
反斜杠后边跟元字符去除特殊功能,比如.
反斜杠后边跟普通字符实现特殊功能,比如d
d 匹配任何十进制数;它相当于类 [0-9]。 D 匹配任何非数字字符;它相当于类 [^0-9]。 s 匹配任何空白字符;它相当于类 [ fv]。 S 匹配任何非空白字符;它相当于类 [^ fv]。 w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。 W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_] 匹配一个特殊字符边界,比如空格 ,&,#等
ret=re.findall('I','I am LIST') print(ret)#[] ret=re.findall(r'I','I am LIST') print(ret)#['I']
看下面两个匹配:
#-----------------------------eg1: import re ret=re.findall('cl','abcle') print(ret)#[] ret=re.findall('c\l','abcle') print(ret)#[] ret=re.findall('c\\l','abcle') print(ret)#['c\l'] ret=re.findall(r'c\l','abcle') print(ret)#['c\l'] #-----------------------------eg2: #之所以选择是因为在ASCII表中是有意义的 m = re.findall('blow', 'blow') print(m) m = re.findall(r'blow', 'blow') print(m)
元字符之分组()
m = re.findall(r'(ad)+', 'add') print(m) ret=re.search('(?P<id>d{2})/(?P<name>w{3})','23/com') print(ret.group())#23/com print(ret.group('id'))#23
元字符之|
ret=re.search('(ab)|d','rabhdg8sd') print(ret.group())#ab
笔记:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 正则:对字符串的模糊匹配 # key:元字符(有特殊功能的字符) import re # re.findall(pattern, string,) # 找到所有的匹配元素,返回列表 #元字符介绍 # . :匹配除 以外的任意符号 #print(re.findall("a.+d","abcd")) # ^:从字符串开始位置匹配 # $:从字符串结尾匹配 # print(re.findall("^yuan","yuandashj342jhg234")) # print(re.findall("yuan$","yuandashj342jhg234yuan")) # * + ? {} :重复 #print(re.findall("[0-9]{4}","af5324jh523hgj34gkhg53453")) #贪婪匹配 print(re.findall("d+","af5324jh523hgj34gkhg53453")) #非贪婪匹配 # print(re.findall("d+?","af5324jh523hgj34gkhg53453")) # print(re.findall("(abcd)*?","af5324jh523hgj34gkhg53453")) # 字符集 []: 起一个或者的意思 # print(re.findall("a[bc]d","hasdabdjhacd")) #注意: * ,+.等元字符都是普通符号, - ^ # print(re.findall("[0-9]+","dashj342jhg234")) # print(re.findall("[a-z]+","dashj342jhg234")) # # print(re.findall("[^d]+","d2a2fhj87fgj")) # ():分组 # print(re.findall("(ad)+","addd")) # print(re.findall("(ad)+yuan","adddyuangfsdui")) # print(re.findall("(?:ad)+yuan","adadyuangfsdui")) # print(re.findall("(?:d)+yuan","adad678423yuang4234fsdui")) #命名分组 #ret8=re.search(r"(?P<A>w+)\aticles\(?P<id>d{4})",r"yuanaticles1234") #ret8=re.search(r"a\nb",r"a b") #print(ret8) # print(ret8.group("id")) # print(ret8.group("A")) # # | :或 # # print(re.findall("www.(?:oldboy|baidu).com","www.oldboy.com")) # :转义 # 1 后面加一个元字符使其变成普通符号 . * # 2 将一些普通符号变成特殊符号 比如 d w # print(re.findall("d+.?d**d+.?d*","-2*6+7*45+1.456*3-8/4")) # print(re.findall("w","$da@s4 234")) # print(re.findall("asb","a badf")) # print(re.findall("\bI","hello I am LIA")) # print(re.findall(r"dI","hello 654I am LIA")) # print(re.findall(r"c\l","abcl")) # re的方法 # re.findall() # s=re.finditer("d+","ad324das32") # print(s) # # print(next(s).group()) # print(next(s).group()) # "(3+7*2+27+7+(4/2+1))+3" # search;只匹配第一个结果 # ret=re.search("d+","djksf34asd3") # print(ret.group()) # # #match:只在字符串开始的位置匹配 # ret=re.match("d+","423djksf34asd3") # print(ret.group()) #split 分割 # s2=re.split("d+","fhd3245jskf54skf453sd",2) # print(s2) # # ret3=re.split("l","hello yuan") # print(ret3) # # #sub: 替换 # # ret4=re.sub("d+","A","hello 234jkhh23",1) # print(ret4) # # ret4=re.subn("d+","A","hello 234jkhh23") # print(ret4) #compile: 编译方法 # c=re.compile("d+") # # ret5=c.findall("hello32world53") #== re.findall("d+","hello32world53") # print(ret5) #计算:"1 - 2 * ( (60-30*2+-96) - (-4*3)/ (16-3*2) )" # s1="1+-2++5" # # def addsub(s): # pass # # def muldiv(s): #(60-30*2+-96) # pass # return (60-60+-96) # # def f(s): # s.replace("+-","-") # # # while re.search("([^()]+)", s): # res = re.search("([^()]+)", s) #(60-30*2+-96) # res=muldiv(res) # ret=addsub(res) # else: # res = muldiv(res) # ret = addsub(res) s="2" print(res.group())
插一嘴:注意下ASCII表中一些反斜杠的特殊意义!
八 json&pickle模块(序列化模块)★★★★
之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#---转换类型 d={"name":"yuan"} s=str(d) print(type(s)) d2=eval(s) print(d2[1]) with open("test") as f: for i in f : if type(eval(i.strip()))==dict: print(eval(i.strip())[1]) # 计算 print(eval("12*7+5-3"))
什么是序列化:
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
强调注意:damps、damp、loads,这3个用法要掌握,在json和pickle中3者都是一样的用法。
json
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
JSON表示的对象就是标准的JavaScript语言的对象一个子集,JSON和Python内置的数据类型对应如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import json i=10 s='hello' t=(1,4,6) l=[3,5,7] d={'name':"yuan"} json_str1=json.dumps(i) json_str2=json.dumps(s) json_str3=json.dumps(t) json_str4=json.dumps(l) json_str5=json.dumps(d) print(json_str1) #'10' print(json_str2) #'"hello"' print(json_str3) #'[1, 4, 6]' print(json_str4) #'[3, 5, 7]' print(json_str5) #'{"name": "yuan"}'
python在文本中的使用:
#----------------------------序列化 import json dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> data=json.dumps(dic) print("type",type(data))#<class 'str'> print("data",data) f=open('序列化对象','w') f.write(data) #-------------------等价于json.dump(dic,f) f.close() #-----------------------------反序列化<br> import json f=open('序列化对象') new_data=json.loads(f.read())# 等价于data=json.load(f) print(type(new_data))
import json i=10 s='hello' t=(1,4,6) l=[3,5,7] d={'name':"yuan"} json_str1=json.dumps(i) json_str2=json.dumps(s) json_str3=json.dumps(t) json_str4=json.dumps(l) json_str5=json.dumps(d) print(json_str1) #'10' print(json_str2) #'"hello"' print(json_str3) #'[1, 4, 6]' print(json_str4) #'[3, 5, 7]' print(json_str5) #'{"name": "yuan"}'
d={"河北":["廊坊","保定"],"湖南":["长沙","韶山"]} d={'name':"egon"} s=json.dumps(d) # 将字典d转为json字符串---序列化 print(type(s)) print(s) f=open("new",'w') f.write(s) f.close() # -------------- dump方式 f=open("new2",'w') json.dump(d,f)#---------1 转成json字符串 2 将json字符串写入f里 f.close() #-----------------反序列化 f=open("new") data=f.read() data2=json.loads(data) print(data2["name"]) #------练习 f=open("new3") data=f.read() ret=json.loads(data) # ret=[123] print(type(ret[0]))
pickle
##----------------------------序列化 import pickle dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> j=pickle.dumps(dic) print(type(j))#<class 'bytes'> f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes' f.write(j) #-------------------等价于pickle.dump(dic,f) f.close() #-------------------------反序列化 import pickle f=open('序列化对象_pickle','rb') data=pickle.loads(f.read())# 等价于data=pickle.load(f) print(data['age'])
import pickle import datetime t=datetime.datetime.now() d={"data":t} json.dump(d,open("new4","w")) d={"name":"alvin"} s=pickle.dumps(d) print(s) print(type(s)) f=open('new5',"wb") f.write(s) f.close() f=open("new5","rb") data=pickle.loads(f.read()) print(data)
九 xml模块★★
十 configparser模块★★
十一 shutil模块
十二 requests模块
请看这里详解:http://www.cnblogs.com/wangyongsong/p/7445322.html#_label0
使用Python的Requests库进行web接口测试:http://blog.csdn.net/liuchunming033/article/details/45538205
十三 paramiko
十四 shelve模块★★★
十五 subprocess模块★★★★
常用subprocess方法示例:
#执行命令,返回命令执行状态 , 0 or 非0 >>> retcode = subprocess.call(["ls", "-l"]) #执行命令,如果命令结果为0,就正常返回,否则抛异常 >>> subprocess.check_call(["ls", "-l"]) 0 #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') #接收字符串格式命令,并返回结果 >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res >>> res=subprocess.check_output(['ls','-l']) >>> res b'total 0 drwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM ' #上面那些方法,底层都是封装的subprocess.Popen poll() Check if child process has terminated. Returns returncode wait() Wait for child process to terminate. Returns returncode attribute. terminate() 杀掉所启动进程 communicate() 等待任务结束 stdin 标准输入 stdout 标准输出 stderr 标准错误 pid The process ID of the child process. #例子 >>> p = subprocess.Popen("df -h|grep disk",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True) >>> p.stdout.read() b'/dev/disk1 465Gi 64Gi 400Gi 14% 16901472 104938142 14% / '
笔记例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import subprocess 2 3 subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,stderr=subprocess) 4 #执行这个命令得是字符串格式,因此'dir'是字符串格式 #stdout 标准输出内容 #stderr 出错的内容 5 #PIPE 管道,将管道左边的内容丢入管道,管道右边从管道内去拿 6 7 8 res=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE) 9 print(res) 10 11 res.stdout.read() #将管道内的标准内容读取出来,并且读出来的编码格式是bash,是以当前操作系统的编码格式而定的 12 res.stderr.read() #将管道内的错误内容读取出来,并且读出来的编码格式是bash,是以当前操作系统的编码格式而定的 13 14 data=res.stdout.read() 15 data.decode('GBK') #读出内容是什么格式就用什么格式解码
>>> subprocess.run(["ls", "-l"]) # doesn't capture output CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null ')
调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:
p = subprocess.Popen("find / -size +1000000 -exec ls -shl {} ;",shell=True,stdout=subprocess.PIPE) print(p.stdout.read())