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()可以看到匹配到了哪些字段,动态规则可以看到很多

先看套路:

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",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") 是匹配不到的
'\Z' 匹配字符结尾,同$
'\d' 匹配数字0-9
'\D' 匹配非数字
'\w' 匹配[A-Za-z0-9]
'\W' 匹配非[A-Za-z0-9]
'\s' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
'\S'     匹配非空白字符、
'(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","").groupdict("city") 结果{'province': '', 'city': '', 'birthday': ''}

re.search整个里面去搜

最新文章

  1. postman使用之二:数据同步和创建测试集
  2. 十天冲刺---Day1
  3. 获取手机通讯录放入PinnedSectionListView中,按名字首字母排序,并且实现拨打电话功能。
  4. python 批量重命名文件后缀
  5. COS中访问文件的三种方式
  6. 数据结构复习:希尔排序的C++实现
  7. SMI接口,SMI帧结构,MDC/MDIO
  8. Java类的生命周期详解
  9. 【转】Spring的WebServiceTemplate访问WebService的方法及其本质原理
  10. Unity 弹出界面时屏蔽对3D场景的点击
  11. windows下的类似grep命令findstr
  12. JS学习笔记(二)运算符和流程控制语句
  13. 【BZOJ1001】[BeiJing2006]狼抓兔子
  14. springMVC_01认识springMVC
  15. python之多线程 threading.Lock() 和 threading.RLock()
  16. ionic中 ng-repeat下使用ng-model获取不到选中数据问题:
  17. C#基础篇二变量与变量类型
  18. 在 Azure 中创建通用 VM 的托管映像
  19. 阿里云centos7.2 lamp配置
  20. Unity Dotween官方案例学习

热门文章

  1. YTU 2898: C-Z型变换
  2. hdoj--1379--DNA Sorting(排序水题)
  3. 2010–2011, NEERC, Northern Subregional C.Commuting Functions
  4. Java多线程系列四——控制线程执行顺序
  5. 07-11 Linux命令操作
  6. 为什么JavaWeb项目要分层
  7. bzoj 1639: [Usaco2007 Mar]Monthly Expense 月度开支【二分】
  8. 1642: [Usaco2007 Nov]Milking Time 挤奶时间(dp)
  9. mutiset HDOJ 5349 MZL&#39;s simple problem
  10. leetcode650 2 Keys Keyboard