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:表示原生字符串

  • 相关阅读:
    MSSQL大量数据时,建立索引或添加字段后保存更改超时该这么办
    POJ 3261 Milk Patterns (后缀数组)
    POJ 1743 Musical Theme (后缀数组)
    HDU 1496 Equations (HASH)
    694. Distinct Substrings (后缀数组)
    POJ 1222 EXTENDED LIGHTS OUT (枚举 或者 高斯消元)
    POJ 1681· Painter's Problem (位压缩 或 高斯消元)
    POJ 1054 The Troublesome Frog (hash散列)
    HDU 1716 排列2
    HDU 4405 Aeroplane chess (概率DP & 期望)
  • 原文地址:https://www.cnblogs.com/alice-bj/p/8477076.html
Copyright © 2011-2022 走看看