zoukankan      html  css  js  c++  java
  • Python学习第二阶段Day2,模块subprocess、 logging、re

    1、logging

    日志开关,设置全局只打印什么级别的日子,默认是warning以下的都不打印

    改默认级别:依次升高

    logging.debug("")

    logging.info("")

    logging.warning("")

    logging.error("")

    logging.critical("")

    看当前日志级别

    输出到文件里:

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

    #DEBUG以上的都输出了,再执行就往后追加,改成warning后,包含warning和以上级别的输出

    缺少时间啊,下面加上时间

    logging.basicConfig(filename="app.log", level=logging.DEBUG,format='%(asctime)s-%(message)s',datefmt='%Y-%m-%d %H:%M:%S')

    输出:

    2017-07-28 22:40:37-内容

    时间至少一个套路,还有很多套路:见套路表 :

    日志格式

    %(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

    用户输出的消息

    可以打印时间,am  pm模块名,行号,函数名,错误级别,进程号,线程号等

    -------------------------------需求来了-------想要日志即在屏幕上又在文件里同时输出怎么办——?

    Python提供四个类关于日志的

    logger类,提供应用程序可以直接使用的接口,用户直接调用这个接口

    handler类:将logger创建的日志输出到哪里?将logger创建的日志发屏幕,或者记录,或者远程机器或者邮件

    filter类:过滤包含什么字段怎么发,复杂用的比较少

    formatter:决定日志记录的最终输出格式

    会用到三个类

    输出信息前获得一个logger,通常一个模块对应一个logger

    LOG = logging.getLogger("chat.gui")  例如chat.gui为名字

    自己起个名字,MySQL或者ngix 都有两个日志,分别由两个logger输出。分门别类的输出文件

    Logger.setLevel()设置级别,最低级别,低于该级别被忽略

    addfilter()不说了

    addhandler() 通过logger记录一条日志,添加handler到logger通过几个handler,就同时发到几个地方

    几个handler:-------》

    1.StreamHandler 屏幕.使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:StreamHandler([strm])其中strm参数是一个文件对象。默认是sys.stderr

    2.FileHandler  文件    

    每个handler可以分别设置级别

     Handler.setLevel()   Handler.setFormatter()  Handler.addFilter() Handler.remove...

    定义日志格式Format

    可以定义不同的文件格式,文件可以和屏幕不一样

    ch  = logging.formatter("asdfasdfasdf")

    formater 跟handler关联

    hdler.setFormatter(ch)

    吧handler告诉logging

    logger.addHandler(hdler)

    这样子,就实现了日志记录目的地的多样性,和输出格式的多样性

    先getlogger,屏幕,文件handler,再定义两种格式,格式跟handler绑定,再把handler跟logger绑定。

    import logging
    
    # logging.basicConfig(filename="aaaaa.log",
    #                     level=logging.CRITICAL,
    #                     format='%(asctime)s-%(levelname)s : %(message)s',
    #                     datefmt='%Y-%m-%d %H:%M:%S')
    # # level low to top
    # logging.debug("!!!!!debug")
    # logging.info("!!!!info")
    # logging.warning("!!!!warning")
    # logging.error("!!!!error")
    # logging.critical("!!!!!!")
    
    # ---- 在屏幕和文件中输出------------------
    log1 = logging.getLogger("logger1")  # 名为logger1的log1对象
    log1.setLevel(logging.DEBUG)
    
    had1 = logging.StreamHandler()       # 屏幕和级别
    had1.setLevel(logging.INFO)
    
    had2 = logging.FileHandler("had2.log", encoding="utf-8") # 文件和级别
    had2.setLevel(logging.WARN)
    
    fm1 = logging.Formatter('%(asctime)s-%(levelname)s : %(message)s') #格式1
    fm2 = logging.Formatter('%(levelname)s : %(message)s')             # 格式2
    
    had1.setFormatter(fm1)  #绑定formatter
    had2.setFormatter(fm2)
    
    log1.addHandler(had1)   #添加handler
    log1.addHandler(had2)
    
    log1.info("aaaa")
    log1.warning("哈哈哈")
    
    # 屏幕:
    # 2017-07-28 23:11:02,946-INFO : aaaa
    # 2017-07-28 23:11:02,946-WARNING : 哈哈哈
    # 文件:
    # WARNING : 哈哈哈

    再讲一点。

    网站访问量大,日志很多几个G,有时候需要写脚本切割,有的程序可以自动切割

    咱的logger里可以根据时间和大小进行切割

    RotatingFileHandler管理文件大小,达到一定大小改名,依次创建文件。maxBytes指定文件大小

    backupCount用于保留日志文件的个数

    文件自动截断例子按大小

    logging.handlers.RotatingFileHandler(filename="dfa",maxBytes=1,backupCount=3,encoding="utf8")

    一共出现四个log,备份三个,显示最新的,把之前的删了,只保留3个

    文件自动截断按时间:S 秒 M分 H小时 D天 W每星期 midnight每天凌晨

    handlers.TimedRotatingFileHandler(filename="ds",when="S",interval=5,backupCount=3,encoding="utf8")

    5秒截断

    from logging import handlers
    log1 = logging.getLogger("name1")
    hand1 = logging.handlers.RotatingFileHandler(filename="fffff.log",
                                                 maxBytes=1,
                                                 backupCount=3,
                                                 encoding="utf-8")
    # hand1 = logging.handlers.TimedRotatingFileHandler(filename="fffff.log",
    #                                                   when='s',
    #                                                   interval=1,
    #                                                   backupCount=3)
    log1.addHandler(hand1)
    log1.warning("a")
    log1.warning("b")

     2.re模块

    [+-]{2,}   和  (+|-){2,}  一样的

    [+-]{0,1} 和  (+|-)?  一样的

    正则表达式,匹配 “不全是空格” 怎么写?  答案: .*[^ ].*

    re.match 从头开始匹配 match(pattern, string, flags=0)

    re.search 匹配包含  search(pattern, string, flags=0)
    re.findall 把所有匹配到的字符放到以列表中的元素返回 findall(pattern, string, flags=0)
    re.split 以匹配到的字符当做列表分隔符 split(pattern, string, maxsplit=0, flags=0)
    re.sub      匹配字符并替换
    sub(pattern, repl, string, count=0, flags=0)
    “d+” "A" "asdfadfa" 次数


    flags = re.I
    flags = re.M

    re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)

    M(MULTILINE): 多行模式,改变'^''$'的行为(参见上图)
    S(DOTALL): 点任意匹配模式,改变'.'的行为
     re.split 套路:
    import re
    
    str1 = '123 S 456 S 789 S abc S def'
    
    print(re.split('S', str1, maxsplit=0)) #['123 ', ' 456 ', ' 789 ', ' abc ', ' def']
    print(re.split('S', str1, maxsplit=1)) #['123 ', ' 456 S 789 S abc S def']
    print(re.split('S', str1, maxsplit=2)) #['123 ', ' 456 ', ' 789 S abc S def']
    print(re.split('S', str1, maxsplit=3)) #['123 ', ' 456 ', ' 789 ', ' abc S def']
    print(re.split('S', str1, maxsplit=4)) #['123 ', ' 456 ', ' 789 ', ' abc ', ' def']
    print(re.split('S', str1, maxsplit=5)) #['123 ', ' 456 ', ' 789 ', ' abc ', ' def']

    用的场景,经常做文字处理用的比较多,做字符串匹配的

    精确匹配  模糊匹配

    最基本的匹配:

    import re

    re.match("inet", "inet 1123sdfasdf")

    match是从头开始匹配

    匹配不上返回NONE

    匹配上了返回<_sre.SRE_Match object; span=(0,4), match='inet'>

    通过a.group()可以看到匹配到了哪些字段,动态规则可以看到很多

    先看套路:

    '.'     默认匹配除
    之外的任意一个字符,若指定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() 结果 '	'
    'S'     匹配非空白字符、
    '(?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.search整个里面去搜

  • 相关阅读:
    HDU 3416 Marriage Match IV(SPFA+最大流)
    asp.net一些很酷很实用的.Net技巧
    asp.net部分控件使用和开发技巧总结
    ASP_NET Global_asax详解
    asp.net 多字段模糊查询代码
    Asp.net中防止用户多次登录的方法
    SQL Server 事务、异常和游标
    有关Cookie
    asp.net 连接sql server 2005 用户 'sa' 登录失败。asp.net开发第一步连接的细节问题
    asp.net生成高质量缩略图通用函数(c#代码),支持多种生成方式
  • 原文地址:https://www.cnblogs.com/revo/p/7250485.html
Copyright © 2011-2022 走看看