zoukankan      html  css  js  c++  java
  • logging/re

    logging 模块

    很多程序都有记录日志的需求
    logging的日志可以分为 debug(), info(), warning(), error() and critical()5个级别

    1.输出到屏幕上

    import logging  #输出到屏幕上 只显示 warning error critical  不会显示 debug info 
    
    logging.debug('user wrong 3 times')  
    logging.info('user wrong 3 times')
    logging.warning('user wrong 3 times')
    logging.error('user wrong 3 times')
    logging.critical('user wrong 3 times')

    2.输出到文件中

    import logging  #输出到文件中 显示 >= level(ERROR)  若是不设level  不会显示 debug info  
    
    logging.basicConfig(filename='logmsg.log',level=logging.ERROR)
    
    logging.debug('user wrong 3 times')
    logging.info('user wrong 3 times')
    logging.warning('user wrong 3 times')
    logging.error('user wrong 3 times')
    logging.critical('user wrong 3 times')

    3.输出日期格式

    import logging   
    
    logging.basicConfig(filename='logmsg.log', format='%(asctime)s - %(levelno)s - %(levelname)s - %(filename)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.DEBUG)
    # logging.basicConfig(format='%(asctime)s %(message)s',datefmt='%Y-%m-%d %I:%M:%S %p',level=logging.DEBUG)
    
    logging.debug('user wrong 3 times')
    logging.info('user wrong 3 times')
    logging.warning('user wrong 3 times')
    logging.error('user wrong 3 times')
    logging.critical('user wrong 3 times')
    
    除了加时间,还可以自定义一大堆格式,下表就是所有支持的格式
    %(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     用户输出的消息

    4.同时输出到屏幕和文件中:四个组件,类:logger handler filter formatter 

     1 import logging
     2 from logging import handlers
     3 
     4 class IgnoreBackupLogFilter(logging.Filter):
     5     """忽略带db backup 的日志"""
     6     def filter(self, record): #固定写法
     7         return  "db backup" not in record.getMessage() #如果是True就记录
     8 
     9 # 1.生成logger对象
    10 logger= logging.getLogger('web')
    11 logger.setLevel(logging.DEBUG)
    12 
    13 #1.1 把filter对象添加到logger中
    14 logger.addFilter(IgnoreBackupLogFilter())
    15 
    16 #2.生成handler对象
    17 ch = logging.StreamHandler()
    18 # ch.setLevel(logging.INFO)
    19 # fh = logging.FileHandler('lweb.log')
    20 # RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])    按文件大小截断
    21 # fh = handlers.RotatingFileHandler('lweb.log',maxBytes=10,backupCount=3)
    22 # TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])  按时间截断
    23 fh = handlers.TimedRotatingFileHandler('lweb.log',when='S',interval=5,backupCount=3)
    24 # fh.setLevel(logging.WARNING)
    25 
    26 #2.1把handler对象绑定到logger
    27 logger.addHandler(ch)
    28 logger.addHandler(fh)
    29 
    30 #3.生成formatter对象
    31 #3.1把formatter对象绑定到handler对象
    32 file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    33 console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(lineno)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p')
    34 ch.setFormatter(console_formatter)
    35 fh.setFormatter(file_formatter)
    36 
    37 logger.debug('user db backup wrong 3 times')
    38 logger.info('user wrong 3 times')
    39 logger.warning('user wrong 3 times')
    40 logger.error('user db backup wrong 3 times')
    41 logger.critical('user db backup wrong 3 times')
    42 
    43 # 没有给级别 之前 默认是 warning
    44 #handler的级别不能比全局低
    45 #像是一个漏斗 全局过滤之后 才到handler
    46 #全局设置为DEBUG后 console handler 设置为 INFO ,如果输出的日志级别为debug,那就不会在屏幕上打印
    #注意:
    maxBytes用于指定日志文件的最大文件大小
    backupCount用于指定保留的备份文件的个数
    when参数是一个字符串 S秒 M分 H小时 D天 W每星期(interval==0时 代表星期一) midnight 每天凌晨
    interval是时间间隔 

     -------------------------------------------------------------------------------

    re 模块
    正则表达式:字符串的匹配规则

    1.re常见的匹配语法有以下几种

     re.match     从头开始匹配 只匹配一个就返回 场景:手机号 
     re.search    全局匹配 只匹配一个就返回 
     re.findall   把所有匹配到的字符放到以列表中的元素返回 phones = re.findall('1[0-9]{10}', data)
     re.split     以匹配到的字符当做列表分隔符 
     re.sub       匹配字符并替换  
     re.fullmatch 全部匹配  
    
     re.match('[0-9]','123dasd') = <_sre.SRE_Match object; span=(0, 1), match='1'>    
     re.search('[0-9]','abc1d3e') =  <_sre.SRE_Match object; span=(3, 4), match='1'> #
     re.findall('[0-9]','abc1d3e') = ['1', '3']
    注:
    match 和 search 返回是一个对象 是这样拿值的:需要先判断 否则会报错
    res = re.search('[0-9]','abs1d2')
    if res:
        print(res.group())
    
    re.match('sd','sd*sda') == re.search('^sd','sd*sda') == re.search('Asd','sd*sda') == sd  
    re.search('sd$','adssasd') == re.search('sd','adssasd') == sd 
    re.search('[0-9]','alex23') == re.search('d','alex23') == 2 

    2.示例:

    re.search('.','*a2a3sdas') == *       #任意一个字符
    re.search('^sd','sd*sda') == sd       #以什么开头
    re.search('sd$','sdasd')  == sd       #以什么结尾
    re.match('b$','b')  == b              #只匹配一个
    re.search('ab*','abblex') == abb      #*前一个字符0次或多次 
    re.search('ab*','sdad') == a
    re.search('ab+','sdad') == None   
    re.search('ab+','sdabbbd') == abbb   
    re.search('a+','sdaa') == aa          #+前一个字符1次或多次
    re.search('.+','abcd') == abcd        #匹配到所有
    re.search('a?','aasad') == a          #?前一个字符0次或1次
    re.search('a{2}','dddaa') == aa       #{m}前一个字符m次
    re.search('[0-9]','asd232') == 2      #[] 匹配0-9一次 [a-z]
    re.search('[a-z]{1,5}','2lex') == lex #{n,m}匹配前一个字符n到m次 
    re.search('[a|A]lex','alex') == alex  #|或 匹配左或右的字符
    re.search('([a-z]+)([0-9]+)','alex123').groups() == ('alex', '123') #()()分组匹配
    
    re.search('Aalex','alex') == alex    #A以什么开头
    re.search('sd','adssasd') == sd     #以什么结尾
    re.search('d','alex23') == 2         #d匹配数字0-9 
    re.search('d+','alex23') == 23
    re.search('D','alex23') == a         #匹配非数字
    re.search('D+','@*&234alex23') == @*&  
    re.search('w+','!@#23saAS') == 23saAS  #匹配[A-Z a-z 0-9]
    re.search('W+','!$@23saAS') == !$@     #匹配非[A-Z a-z 0-9] 即:特殊字符 
    re.findall('s','alex
    jack
    ma ck	jack') == ['
    ', '
    ', ' ', '	']  #匹配空白字符 
     
     	 
    
    s='61062019991011053'  #分组,可定义成字典 
    re.search('(?P<province>d{3})(?P<city>d{3})(?P<born_year>d{4})',s).groups() == ('610', '620', '1999')
    re.search('(?P<province>d{3})(?P<city>d{3})(?P<born_year>d{4})',s).groupdict() == {'province': '610', 'city': '620', 'born_year': '1999'} 

    3.常用的表达式规则

    '.'     默认匹配除
    之外的任意一个字符,若指定flag DOTALL,(re.S)则匹配任意字符,包括换行
    '^'     匹配字符开头,若指定flags MULTILINE,(re.M)这种也可以匹配上(r"^a","
    abc
    eee",flags=re.MULTILINE)
    '$'     匹配字符结尾, 若指定flags MULTILINE(re.M) ,re.search('foo.$','foo1
    foo2
    ',re.MULTILINE).group() 会匹配到foo1
    '*'     匹配*号前的字符0次或多次, re.search('a*','aaaabac')  结果'aaaa'
    '+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
    '?'     匹配前一个字符1次或0次 ,re.search('b?','alex').group() 匹配b 0次
    '{m}'   匹配前一个字符m次 ,re.search('b{3}','alexbbbs').group()  匹配到'bbb'
    '{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|45)", "abcabca456c").group() 结果为'abcabca45'
    
    
    'A'    只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的,相当于re.match('abc',"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'}

    4.分割:re.split() 替换:re.sub() 全部匹配:re.fullmatch()  全部匹配:pattern = re.compile() pattern.fullmatch() 效率高

    s='alex22jack23jinxin50|mack-oldboy'
    re.split('d+|||-',s) == ['alex', 'jack', 'jinxin', '', 'mack', 'oldboy']
    re.findall('d+|||-',s) = ['22', '23', '50', '|', '-'] 
    s='alex22jack23jinxin50mack-oldboy'
    re.split('\\',s) == ['alex22jack23jinxin50', 'mack-oldboy'] 
    s='9-2*5/3+7/3*99/4*2998+10*568/14'
    re.split('W+',s) == ['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
    re.split('W+',s,maxsplit=3) == ['9', '2', '5', '3+7/3*99/4*2998+10*568/14'] 
    re.split('[-*/+]',s) == ['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
    
    s = 'alex22jack23jinxin50\mack-oldboy'
    re.sub('d+','_',s) == 'alex_jack_jinxin_\mack-oldboy'
    re.sub('d+','_',s,count=2) == 'alex_jack_jinxin50\mack-oldboy' 
    
    re.fullmatch('w+@w+.(com|cn|edu)','alex@oldboyedu.com') # 慢 规则需要转换成bytes需时间
    
    pattern = re.compile('w+@w+.(com|cn|edu)') #快 规则转换bytes1次就可以了
    pattern.fullmatch('alex@oldboyedu.com') == <_sre.SRE_Match object; span=(0, 18), match='alex@oldboyedu.com'>

    5.标识符 Flags 

    re.I   #忽略大小写  re.IGNORECASE
    re.M   #多行模式  re.MULTILINE
    re.S   #改变.的行为,.是任意字符,除了换行符
      re.DOTALL
    re.X   #可对正则 规则 注释  re.VERBOSE 
    
    re.search('a','Alex',re.I) == A 
    re.search('foo.$','foo1
    foo2
    ') == foo2  
    re.search('foo.$','foo1
    foo2
    ',re.M) == foo1  
    re.search('^s','
    sds',re.M) == s  
    re.search('.','
    ') == None 
    re.search('.','
    ',re.S) == 
      
    re.search('.','alex') == a 
    re.search('. #test','alex') == None
    re.search('. #test','alex',re.X) = a

     注:

        [^"] 表示不包含“这个字符

        [^()] 表示不包含()这个括号

    re.search(r'\','asd2sad') == <_sre.SRE_Match object; span=(4, 5), match='\'>
    re.search('\\','asd2sad') == <_sre.SRE_Match object; span=(4, 5), match='\'>
    r:表示原生字符串

  • 相关阅读:
    基于redis实现可靠的分布式锁
    基于react实现无限分级菜单
    利用免费cdn加速webpack单页应用
    研究一下javascript的模块规范(CommonJs/AMD/CMD)
    基于ReactCSSTransitionGroup实现react-router过渡动画
    react + iscroll5 实现完美 下拉刷新,上拉加载
    如何在多线程leader-follower模式下正确的使用boost::asio。
    【深入浅出Linux网络编程】 “实践 -- TCP & UDP”
    【hbase0.96】基于hadoop搭建hbase的心得
    【hadoop2.2(yarn)】基于yarn成功执行分布式map-reduce,记录问题解决过程。
  • 原文地址:https://www.cnblogs.com/alice-bj/p/8477076.html
Copyright © 2011-2022 走看看