zoukankan      html  css  js  c++  java
  • 利用logging.basicConfig生成文件--中文乱码解决方法

    logging 模块

    logging 模块是 Python 内置的标准模块, 主要用于输出运行日志
    logging 可以设置信息输出位置, 以及如何输出
    1. 可以设置输出日志的等级, 保存路径, 日志文件回滚等
    2. 可以通过设置不同的日志等级, 在 release 版本中只输出重要信息,而不必显示大量的调试信息

    为什么要使用 logging 模块

    在程序的运行过程中, 难免会产生一些重要的数据信息.
    有些是可以展示给用户看的, 有些就需要默默的收集起来, 作为日后调试优化系统时的重要参考.
    处理繁琐的日志读写, Python早已为我们提供了便捷的模块 logging

    如何使用 logging 模块

    导入模块

    import logging
    
    

    logging 模块提供了非常丰富的功能 (在此仅介绍本人常用的一些功能)

    一个如何使用 logging 模块的简单例子

    import logging
    logging.basicConfig(level=logging.DEBUG,
                       format="%(asctime)s	"
                       "%(filename)s	"
                       "[line:%(lineno)d]	"
                       "%(levelname)s
    "
                       "%(message)s",
                       datefmt="%a, %d %b %Y %H:%M:%S"
                       )
    
    logging.debug("调试信息")
    logging.info("普通信息")
    logging.warning("警告信息")
    logging.error("错误信息")
    logging.critical("严重错误信息")
    
    

    功能及参数解析

    设置基本配置
    logging.basicConfig(
    
    指定日志文件名称
    filename="filename"
    
    指定日志文件的打开模式, 'w'或者'a'
    filemode="w" 或 "a"
    
    指定输出的格式和内容
    format="格式和内容"
    
    Textual time when the LogRecord was created
    日志记录时的文本时间
    "%(asctime)s"
    
    Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    打印日志级别的数值
    %(levelno)s
    
    Text logging level for the message ("DEBUG", "INFO",  "WARNING", "ERROR", "CRITICAL")
    打印日志级别的名称
    %(levelname)s
    
    Full pathname of the source file where the logging call was issued (if available)
    打印当前执行程序的路径,相当于打印sys.argv[0]
    %(pathname)s:
    
    Filename portion of pathname
    打印当前执行程序名
    %(filename)s
    
    Function name
    打印日志的当前函数
    %(funcName)s
    
    Source line number where the logging call was issued (if available)
    打印日志的当前行号
    %(lineno)d
    
    The result of record.getMessage(), computed just as the record is emitted
    打印日志信息
    %(message)s
    
    Thread ID (if available)
    打印线程ID
    %(thread)d
    
    Thread name (if available)
    打印线程名称
    %(threadName)s
    
    Process ID (if available)
    打印进程ID
    %(process)d
    
    Use the specified date/time format
    使用指定的日期/时间格式
    %a : 周    %d : 日    %b : 月    %Y : 年(XXXX)    %H : 时    %M : 分    %S : 秒
    datefmt="%a, %d %b %Y %H:%M:%S"
    )
    
    

    如何利用 logging 模块写日志文件

    本人暂时只掌握两种写入文件的方法

    利用 logger 对象

    import logging
    logger = logging.getLogger()  # 实例化一个logger对象
    logger.setLevel(logging.INFO)  # 设置初始显示级别
    
    # 创建一个文件句柄
    file_handle = logging.FileHandler("log", encoding="UTF-8")
    
    # 创建一个流句柄
    stream_handle = logging.StreamHandler()
    
    # 创建一个输出格式
    fmt = logging.Formatter(f"{'*'*28}
    "
                            "> %(asctime)s
    "
                            "> %(levelname)s - "
                            "%(filename)s - "
                            "[line:%(lineno)d]
    "
                            f"{'-'*40}
    "
                            "  %(message)s
    "
                            f"{'-'*40}
    
    ",
                            datefmt="%a, %d %b %Y"
                            "%H:%M:%S"
                            )
    
    file_handle.setFormatter(fmt)  # 文件句柄设置格式
    # stream_handle.setFormatter(fmt)  # 流句柄设置格式
    
    logger.addHandler(file_handle)  # logger对象绑定文件句柄
    # logger.addHandler(stream_handle)  # logger对象绑定流句柄
    
    logger.info("这是程序运行过程中的一条提示")
    
    

    利用logging.basicConfig基本配置

    利用这种方法将日志写入文件通常不支持中文
    中文将显示为乱码, 虽然网上有许多处理方法, 但是为什么我们不在一开始就解决中文乱码的问题呢
    在此我将分享我的解决方法

    import logging
    file = open("log", encoding="utf-8", mode="a")
    logging.basicConfig(level=logging.DEBUG,
                        stream=file,
                        format="%(asctime)s "
                               "%(filename)s [line:%(lineno)d] "
                               "%(levelname)s
    "
                               "%(message)s",
                        datefmt="%a, %d %b %Y %H:%M:%S"
                        )
    
    logging.debug("调试信息")
    logging.info("普通信息")
    logging.warning("警告信息")
    logging.error("错误信息")
    logging.critical("严重错误信息")
    file.close()
    
    

    stream : 日志的输出流,可以指定输出到 sys.stderr, sys.stdout 或者文件, 默认输出到 sys.stderr, 当 stream 和 filename 同时指定时, stream 被忽略
    利用 stream 输出到文件便可以解决编码问题, 然而这样一来却也带来了一些问题
    首先, 文件在程序运行过程中必须始终保持打开状态
    其次, 不能同时进行写入文件与控制台输出

    以上
    未来学习工作中发现更好的解决措施会回来填坑...

  • 相关阅读:
    BZOJ 2300凸包+离线
    BZOJ 4140 凸包+二进制分组
    BZOJ 2178 Simpson积分
    BZOJ 4828 DP+BFS
    BZOJ 1845 Simpson积分
    BZOJ 1137 半平面交
    Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树
    Codeforces Round 411 Div.2 题解
    BZOJ 4530 LCT/线段树合并
    BZOJ 2946 SA/SAM
  • 原文地址:https://www.cnblogs.com/dmcs95/p/10660372.html
Copyright © 2011-2022 走看看