我为Python2 here问了这个问题,但当答案不再适用于Python3.2.3时,我又碰到了这个问题.

下面是适用于Python 2.7.3的代码:

import logging

# Attempt to set up a Python3 logger than will print custom messages
# based on each message's logging level.
# The technique recommended for Python2 does not appear to work for
# Python3

class CustomConsoleFormatter(logging.Formatter):
    """
    Modify the way DEBUG messages are displayed.

    """
    def __init__(self, fmt="%(levelno)d: %(msg)s"):
        logging.Formatter.__init__(self, fmt=fmt)

    def format(self, record):

        # Remember the original format
        format_orig = self._fmt

        if record.levelno == logging.DEBUG:
            self._fmt = "DEBUG: %(msg)s"

        # Call the original formatter to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format
        self._fmt = format_orig

        return result


# Set up a logger
my_logger = logging.getLogger("my_custom_logger")
my_logger.setLevel(logging.DEBUG)

my_formatter = CustomConsoleFormatter()

console_handler = logging.StreamHandler()
console_handler.setFormatter(my_formatter)

my_logger.addHandler(console_handler)

my_logger.debug("This is a DEBUG-level message")
my_logger.info("This is an INFO-level message")

使用Python 2.7.3运行:

tcsh-16: python demo_python_2.7.3.py 
DEBUG: This is a DEBUG-level message
20: This is an INFO-level message


据我所知,转换到Python3只需要对CustomConsoleFormat稍加修改.init():

def __init__(self):
    super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

在Python 3.2.3上:

tcsh-26: python3 demo_python_3.2.3.py
10: This is a DEBUG-level message
20: This is an INFO-level message


我试着在Python3源代码中挖掘,它看起来像是PercentStyle的实例化在重击self_fmt在我自己动手后.

我的伐木排骨已经不能解决这个问题了.

有谁能推荐另一种方式,或者指出我忽略了什么?

推荐答案

通过一点挖掘,我能够修改Python2解决方案以与Python3一起使用.在Python2中,需要临时覆盖Formatter._fmt.在Python3中,对多种格式字符串类型的支持要求我们临时覆盖Formatter._style._fmt.

# Custom formatter
class MyFormatter(logging.Formatter):

    err_fmt  = "ERROR: %(msg)s"
    dbg_fmt  = "DBG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "%(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')  
    
    def format(self, record):

        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = MyFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = MyFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = MyFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result

下面是Halloleo关于如何在脚本中使用上述内容的示例(从Python2 version of this question开始):

fmt = MyFormatter()
hdlr = logging.StreamHandler(sys.stdout)

hdlr.setFormatter(fmt)
logging.root.addHandler(hdlr)
logging.root.setLevel(logging.DEBUG)

Python-3.x相关问答推荐

PythonPandas -通过知道位置(Loc)而不是索引来删除行

泛型类型的参数的静态类型

如何将项目添加到Python中具有固定大小的列表列表中

Python - 根据条件附加 NULL 值

CSV-DAT 转换时将引号添加到数据中

tkinter/python3.9 中的 Entry 子类和用户输入重复的问题

使用 multiprocessing 处理图像

Python 列表求和所有出现的保留顺序

将 pandas Timestamp() 转换为 datetime.datetime() 以支持 peewee DateTimeField()

如何在 Telethon 中向机器人发送发送表情符号

Einsum 对于张量乘法很慢

如何使用 Selenium by class_name 从大学橄榄球数据中抓取图像 url 列表

保存 StandardScaler() 模型以用于新数据集

获取嵌套字典的所有键

PySpark python 问题:Py4JJavaError: An error occurred while calling o48.showString

TypeError:列表索引必须是整数或切片,而不是列表

TypeError:多个基地有实例布局冲突

在 Ipython 中使用 Pylint (Jupyter-Notebook)

将 Python SIGINT 重置为默认信号处理程序

Python,Docker - ascii编解码器无法编码字符