面向对像(8day) 正则表达式,日志格式,json模块
logging模块
import logging
import logging
# debug info warning(默认) error critical
#1 congfig函数
# logging.basicConfig(level=logging.DEBUG,
# format="%(asctime)s [%(lineno)s] %(message)s",
# datefmt="%Y-%m-%d %H:%M:%S",
# filename="logger",
# filemode="a"
# )
# logging.debug('debug message')
# num=1000
# logging.info('cost %s'%num)
# logging.warning('warning messagegfdsgsdfg') #
#
# logging.error('error message')
#
# logging.critical('critical message')
#配置两种方式: 1 congfig 2 logger
# 2 logger对象
设置日志的固定格式,比较常用的就是用这个logger对像方式,而且,
固定的设置成一个函数,到使用的地方就可以调用
fh,sh是输出对像;fm为输出格式的对像,我想让输出按fm的格式来输出,就是吃的过程,用fh.setFormatter方法,让输出有格式的对像
而让logger有fh,sh的属性就是用logger.addHandler方法来吃
使用logger对像来管理日志,先创建logger对像,而fh,sh是logging的两个对像,分别输出到文件
和屏幕的属性,而logger想要拿到这个属性就调用了logger.addHandler吸这个动作,把别人的属性变成自己的
然后logger就有了这个属性
fm-->fh,sh--->logger,fm对像被fh,sh对像拿到,然后,fh,sh对像又被logger对像拿到使用,非常的死,以后就用函数来固定使用
大鱼吃小鱼的过程
def get_logger():
logger=logging.getLogger()
fh=logging.FileHandler("logger2")
sh=logging.StreamHandler()
logger.setLevel(logging.DEBUG) #设定日志输出等级
fm=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
logger.addHandler(fh)
logger.addHandler(sh)
fh.setFormatter(fm)
sh.setFormatter(fm)
return logger
Logger=get_logger()
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')
#logger,先创建一个logger对像 默认也是warning,只有之上的才显示 logger=logging.getLogger()# #1 logger是一个吸的过程,先去吸两个输出对像,文件输出和屏幕输出 #创建输出对像 fh=logging.FileHandler("logger2")#输出的文件名 sh=logging.StreamHandler() #创建格式对像 fm=logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") #输出对像拿到格式对像的属性,吸 fh.setFormatter(fm) sh.setFormatter(fm) #logger吸上面两个定义的对像,分别流向屏幕和文件 logger.addHandler(fh)#追加写 logger.addHandler(sh) logger.debug('info message式大砝码夺在') logger.info('info message') logger.warning('info message砝码砝码')# logger.error('info message在在') logger.critical('info message') # # logger # fh sh # fm # fm -->fh, sh - -->logger, fm对像被fh, sh对像拿到,然后,fh, sh对像又被logger对像拿到使用,非常的死,以后就用函数来固定使用 # # 大鱼吃小鱼的过程 #以后用就设成个函数,返回个对像, def get_logger(): logger = logging.getLogger() fh = logging.FileHandler("logger2") sh = logging.StreamHandler() logger.setLevel(logging.DEBUG) # 设定日志输出等级 fm = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") logger.addHandler(fh) logger.addHandler(sh) fh.setFormatter(fm) sh.setFormatter(fm) return logger Logger = get_logger() 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')
json模块,非常重要
参考:http://www.cnblogs.com/yuanchenqi/articles/6766020.html
json.dumps : dict转成str
json.loads:str转成dict
# d={"河北":["廊坊","保定"],"湖南":["长沙","韶山"]} # # s=str(d) # with open("data","w") as f: # f.write(s) # with open("data") as f2: # s2=f2.read() # d2=eval(s2) # # print(d2["河北"]) # '{"河北":["廊坊","保定"],"湖南":["长沙","韶山"]}' # print(eval("12+34*34")) import json json像个桥梁一样,你web,前后端来进行数据的交互都是通过json来做的,所以太重要了 json是一种数据格式 这嘛重要只有两种方法,序列化,和反序列化 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"}' json只认识[]不认识()所以,所有的tupel,列表都转换成[],还有python对应的json字符串要加"", loads之前不一定要dumps只要符合json的数据类型格式的都行(都能反序列化),你写在文件中的字典类型的key一定要用""写,''不认,还有字符,也要写"" 具体可以看博客的一张图,没有集合这种型式,json # # d={"河北":["廊坊","保定"],"湖南":["长沙","韶山"]} # # d={'name':"egon"} # # # s=json.dumps(d) # 将字典d转为json字符串---序列化,而且name序列化成json值之后,你打印出来的name必是加""的,这是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能序列化任意的数据类型,而Json不行,所以如果是两个python之间的交接,用pickle足够了,也只有dumps,loads,但是不同的前后端要用json了,
另外注意,pickle序列化,的都是以二进制,所以wb方式,读也是rb方式
#----------------------------------pickle-------------------- 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)
正则表达式
# 正则表达式:是对字符串的模糊匹配 # key:元字符(有特殊功能的字符) import re 正则方法 # re.findall(pattern, string,) # 找到所有的匹配元素,以一个列表形式返回 \d 匹配数字 #元字符介绍(就是重复前面一个符号) # * + ? {} :关于重复,此元字符前面的字符出现的次数 * 0到无穷,(*范围,前面的字符出现) + 1到无穷次,(+范围,前面的字符出现) ? 0到1次,(?范围,前面的字符出现) {} 任意次,{n,m} ({}前面的字符出现的一个范围) re.findall("ab{3}c","abbbc")出现3次,准确的出现3次 {0,}匹配0到无穷次, # . :匹配除\n以外的任意符号 re.findall("p..h","hello,python") #print(re.findall("a.+d","abcd")) # ^:从字符串开始位置匹配 # $:从字符串结尾匹配 # print(re.findall("^yuan","yuandashj342jhg234"))以yuan开头, # print(re.findall("yuan$","yuandashj342jhg234yuan"))以yuan结尾,必须四个全配 #print(re.findall("[0-9]{4}","af5324jh523hgj34gkhg53453")) #贪婪匹配 print(re.findall("\d+","af5324jh523hgj34gkhg53453")) #非贪婪匹配 # print(re.findall("\d+?","af5324jh523hgj34gkhg53453")) # print(re.findall("(abc\d)*?","af5324jh523hgj34gkhg53453")) # 字符集 []: 是表示一个字符,或者,的意思 # print(re.findall("a[bc]d","hasdabdjhacd")) #注意: * ,+. 等元字符都是普通符号, 在[*,+,. ]里就是个普通符号了 - ^ \ 这几个有特殊功能例外 -是个范围[0-9]代表一个数字,[0-9]+一个到多个数字 跟\d效果一样 ;[a-z]+连着的小字母都匹配 [^2],取反,除了2以外的一个字符,[^\d]表示一个非数字的字符 # print(re.findall("[0-9]+","dashj342jhg234")) # print(re.findall("[a-z]+","dashj342jhg234")) # # print(re.findall("[^\d]+","d2a2fhj87fgj")) # () 分组 # print(re.findall("(ad)+","addd"))结果,就只有一个['ad'],ad做了一个整体来匹配 # print(re.findall("(ad)+yuan","adddyuangfsdui")),这个是匹配不到的,两个dd没匹配上ad # 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"yuan\aticles\1234") #ret8=re.search(r"a\\nb",r"a\nb") #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("a\sb","a badf")) # print(re.findall("\\bI","hello I am LIA")) \b就是匹配一个特殊符号的边界,不匹配符号,\\是一个普通的\ # print(re.findall(r"\dI","hello 654I am LIA")) 加r是,告诉python解释器,所有的\不要给我转义,直接交给正则表达式,原生字符串不转义,按普通的符号交给正则 # print(re.findall(r"c\\l","abc\l")) 加r是,告诉python解释器,所有的\不要给我转义,直接交给正则表达式,原生字符串不转义,按普通的符号交给正则去处理 # 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())