python日志输出你会想到啥?不妨来看看这几个模块的用法
off999 2024-10-07 12:17 45 浏览 0 评论
日志可以说是每个开发人员必备的功能 ,通过它可以方便的帮我们找出程序中的一些错误 ,因此要使用到一个好的日志模块或方法对我们来说,也是比较重要的 。接下来我们就介绍python中支持输出日志的4个方法或模块,它们分别是:
- print()
- pprint()
- logging
- loguru
1.print()
print是一个内置函数,可以直接调用,也是在写代码时最常用的打印函数 。我们最常用的就是输入一个变量,然后进行打印,其实在print中有如下参数:
- sep : 在值之间插入字符串,默认为空格。
- end : 在最后一个值之后附加的字符串,默认为换行符
- flush: 是否强制刷新,这个参数一般和file一起使用 。
- file : 输出到文件
代码示例:
以下对print中不同的参数进行代码示例
将print语句的输出信息写入到文件中 。需要注意的是:若输出到文件时,不加flush 或者flush=False时,默认先将print输出信息写入内存中,当文件关闭时才把文件进行输出 ;但是当flush=True时,每次print的信息都会直接写入到文件中 。
2.pprint()
pprint()方法能够打印python的各种数据结构,使用这个方法可以将数据结构美化,从而在看起来更加方便 。
pprint()方法是包含在pprint模块中的,在pprint模块中还有好几个方法,这里我们只介绍pprint()方法
若要使用pprint,需要先进行安装 。
安装命令:
pip install pprint接下来,我们需要导入pprint(),
导入命令:
from pprint import pprintpprint方法中也可以传入多个参数 ,具体如下:
命令说明:
pprint(object, stream=None, indent=1, width=80, depth=None, *,compact=False)- object :具体的数据
- stream:输出文件流,若不填写,默认为控制台
- indent: 数据进行换行时的缩进
- width : 每一行数据的默认宽度(长度),超过后换行
- depth: 要展示数据结构的深度,超过深度会以...代替
示例代码:
1.通过width和indent可以控制数据的每行宽度和每行开头的缩进
2.通过depth可以控制数据结构的层级,多于参数中的值,数据结构会被...代替。
3.将数据输出到文件中
3.logging模块
logging是python内置的一个日志模块,它可以将日志分为不同的级别,按不同级别的日志进行输出 ;其次它还可以对日志进行格式化,对输出的信息显示更加美观 ; 同时也支持将日志输出到不同地方,如控制台或文件中 。
在logging中提供了很多的函数和类,以满足日志输出的不同需求,以下表格记录了logging模块中主要的函数,类或者常量 。
3.1 输出不同级别日志
通过上图我们可以看到,无论何种实现方式,只是将warning级别及以上日志输出,但是并没有讲debug和info日志输出 。这是什么原因导致的呢 ?
其实答案就是在logging模块内,它会设置一个默认的日志级别,当我们调用不同的日志方法时,其内部要进行一步和默认的日志进行比较,若小于设置的日志级别,则不会往出输出 。而默认的日志级别就是WARNING。以下为logging模块内部源代码设置,经实测,修改此默认设置会改变日志输出 。
root = RootLogger(WARNING)
Logger.root = root
Logger.manager = Manager(Logger.root)3.2 基本配置方法basicConfig()
在上一个部分我们看到,每条日志的输出格式为:
WARNING:root:这是一条warning日志
ERROR:root:这是一条error日志总结起来就是: 日志级别:日志名称:日志内容 ,但是这样的日志格式太过简陋,不能很好帮我们定位程序中出现的问题 。那如果我们想自定义日志的输出格式怎么办呢 ? 其中方法之一就是使用basicConfig() .
首先我们来看下,basicConfig都有哪些参数 ?
配置日志信息,将日志写入到文件中 :
配置日志级别和格式:
通过level可以设置日志级别,可以通过format可以自定义日志格式 ,具体如下:
最后需要说明的是,通过basicConfig配置后的对象是一个单例,只要进行了自定义配置,后续再使用logging就都会按照自定义的配置执行了 。
3.3 日志处理器:Handler
Handler的作用是将日志分发到handler指定的位置,如控制台、文件、网络、邮件等。但是需要注意的是,Handler是一个父类,在Handler类中并没有去实现如上面描述的功能(输出到文件,控制台等),真正完成这些功能的是Handler的子类。所以,我们要使用Handler的功能,一般都是直接调用Handler的子类 ,具体包含的子类有:
但是在Handler这个类中,有两个常用的方法 ,无论使用哪个子类,基本都会使用到这两个方法 。
3.4 日志格式化器:Formatter
Formater对象用于配置日志信息的顺序、结构和内容。虽然这个类的构造方法中有三个参数,但是有只有一个是常用到的,也就是要输出日志的格式内容 。
比如我要自定义的日志格式为:
import logging
#自定义日志格式
fmt = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
formatter = logging.Formatter(fmt)若想要按照如上格式输出,还需要将创建的formatter加入到日志处理器中 。所以,以上代码还需完善,具体如下:
import logging
# 创建控制台处理器
sh = logging.StreamHandler()
#自定义日志格式
fmt = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
formatter = logging.Formatter(fmt)
# 将日志格式化器加入到处理器
sh.setFormatter(formatter)但是即便这样,还是无法按照自定义格式输出 ,这是因为我们还需要将处理器最终加入到日志器中 。那么接下来我们就来了解下日志器 。
3.5 日志器:Logger
日志器的主要作用是配置日志级别和接收日志处理器中的对象,以确定最终将日志要输出到哪 ?所以我们要先初始化一个Logger的对象 。
logger = logging.Logger('test',level=logging.DEBUG)在初始化logger对象时,需要在Logger中传递两个参数,第一个是日志名称,第二个是日志级别 。如上所示 。
初始化日志对象后,即可通过Logger中的addHandler()方法来添加日志处理器了 ,具体如下:
需要注意的是,以上申明日志器对象时,必须要传入一个日志名称,而这个名称,有时候并非是一个重要选项 ,可能我们也不关注这个日志名称是什么? 那么我们可否不传递这个日志名称而直接获得一个Logger对象呢 ? 答案是可以的 ,但是需要调用一个方法,即getLogger()。也就是说上面的初始化logger对象代码可以修改为如下:
import logging
logger = logging.getLogger()那么,通过如上申明logger也能正常使用,这时如果传递了日志name,则日志名字就会按照传递后的名字显示,若没有传递,则默认为root .
3.6 日志过滤器:Filter
Filter可以被Logger用来做更细粒度的、更复杂的过滤功能。它只允许某个logger层级下的日志事件通过过滤。该类定义如下:
class logging.Filter(name='')
filter(record)比如,一个filter实例化时传递的name参数值为'A.B',那么该filter实例将只允许名称为类似如下规则的loggers产生的日志记录通过过滤:'A.B','A.B,C','A.B.C.D','A.B.D',而名称为'A.BB', 'B.A.B'的loggers产生的日志则会被过滤掉。如果name的值为空字符串,则允许所有的日志事件通过过滤器。
3.7 实现自定义日志器的流程
当需要在程序中封装自己的日志处理器的话,我们就会用到了处理器(Handler),格式化器(Formatter)及日志器(Logger)了,而使用他们的基本流程也都是如下所示 :
以下为代码示例
def log_config():
#创建日志器
logger = logging.getLogger()
logger.setLevel(logging.INFO)
#创建控制台输出器
sh = logging.StreamHandler()
#创建文件输出器
log_dir = Path(BASE_DIR + '/log')
if not log_dir.is_dir():
os.mkdir(log_dir)
log_file = os.path.join(log_dir,'ihrm.log')
th = logging.handlers.TimedRotatingFileHandler(log_file,when='midnight',interval=1,backupCount=7,encoding='utf-8')
#创建格式化器
fmt = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
formatter = logging.Formatter(fmt)
#把格式化器加入输出器
sh.setFormatter(formatter)
th.setFormatter(formatter)
#把处理器加入日志器
logger.addHandler(sh)
logger.addHandler(th)4.loguru模块
和logging一样,loguru也是一个日志库,所不同的是,这个第三方库基本不需要做任何配置就可以直接使用,而且很重要的一点是使用的logger对象无需创建,直接导入的logger对象也是单例模式,直接使用即可。要想使用它需要先安装。
安装命令:
pip install loguru导入
from loguru import logger4.1 输出不同级别的日志
从以上可以看到,我们直接导入的logger其实就是一个对象 ,通过该对象可以直接调用不同级别的日志方法 。另外,我们也注意到,该日志输出后还是带不同颜色的 ,而且默认输出日志格式就很清晰,比较容易定位问题 。
4.2 输出到文件:add方法
很多情况下,我们会将日志输出到文件 ,那么对于loguru输出到文件的配置也有非常强大的支持 ,比如格式按级别输出,输出多个文件,文件自动分隔等等 。那么这些功能的支持其实就需要一个方法就可以搞定,也就是add方法 。
常用参数
可以看到,add方法中其实有很多参数 ,那么接下来我们先了解几个常用的参数 。
- sys.stderr : 输出文件
- format :设置格式化
- filter : 过滤器
- level :设置级别
日志分隔
如果想对日志进行分隔,比如按文件大小分隔,或者定时分隔,在add方法中,只需要一个参数即可搞定 。这个参数就是rotation,具体代码如下:
logger.add("file_1.log", rotation="500 MB") # 每隔500M重新生成一个新文件
logger.add("file_2.log", rotation="12:00") # 每天12点生成一个新文件
logger.add("file_3.log", rotation="1 week") # 每隔一周生成一个新文件
logger.add("file_X.log", retention="10 days") # 每隔10天生成一个新文件
logger.add("file_Y.log", compression="zip") # 文件写入后同时压缩该文件为zip格式4.3 日志格式化
除了以上功能外,输出的日志可以像format方法一样,可以对日志进行格式化 。
4.4 记录崩溃日志
在很多情况下,在代码运行出错的地方没有配置日志 ,我们就没法追踪错误所在了 。但是使用loguru的装饰器,我们就可以直接进行 跟着错误日志了 的记录了,类似这样的配置即可:
from loguru import logger
@logger.catch
def my_function(x, y, z):
# An error? It's caught anyway!
return 1 / (x + y + z)
my_function(0,0,0)可以看出,当程序报错时,我们可以很清晰的看到错误的代码以及报错后各种输出信息 。
5.总结
最后,我们将上面的4个方法或模块放在一起做一个对比,以确定它们各自的优缺点 。
从上图基本可以看出 ,它们都各有优势 , 我们不好说那个是最好的,但都有各自的使用场景 。
- print : 更加使用程序快速打印,不在乎日志格式,只想更快看到结果 ,一般用于程序的某个片段或者单点进行调试输出 。
- pprint: 对元组,列表,字典数据打印更加直观友好,若输出的是这种格式,可以优先考虑pprint .
- logging :对实现一个系统或框架时比较合适 ,而且对日志需求有更高要求,可以优先考虑logging
- loguru :对实现一个系统或框架也比较合适 ,但是更加轻量化,不需要配置 ,若对日志需求要求不高,可优先考虑loguru
相关推荐
- 安全教育登录入口平台(安全教育登录入口平台官网)
-
122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...
- 大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)
-
大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...
-
- 哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
-
要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...
-
2026-02-04 09:03 off999
- 电信宽带测速官网入口(电信宽带测速官网入口app)
-
这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...
- 植物大战僵尸95版手机下载(植物大战僵尸95 版下载)
-
1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...
- 免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)
-
1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...
- 2025世界杯赛程表(2025世界杯在哪个国家)
-
2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...
- 下载搜狐视频电视剧(搜狐电视剧下载安装)
-
搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...
- 永久免费听歌网站(丫丫音乐网)
-
可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...
- 音乐格式转换mp3软件(音乐格式转换器免费版)
-
有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...
- 电子书txt下载(免费的最全的小说阅读器)
-
1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...
- 最好免费观看高清电影(播放免费的最好看的电影)
-
在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...
- 孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)
-
要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
win7系统还原步骤图解(win7还原电脑系统的步骤)
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
16949认证费用是多少(16949审核员太难考了)
-
linux软件(linux软件图标)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
windows7旗舰版多少钱(win7旗舰版要多少钱)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
