You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python日志文件中格式化输出字典为整块内容?

问题:Python日志中字典内容的整块格式化输出需求

已配置可输出到流与文件的logging处理器,处理字典数据时希望将其格式化为整块内容输出到日志文件,而非单行分散显示。在编写字典专属自定义格式化器前,想了解是否有现成实现方案。

期望输出示例

2024-02-13 13:27:03,685 [DEBUG] root: shelf_name = 'some shelf',
                                      url = 'http://a_url',
                                      creation_date = '02/12/2024'
2024-02-13 13:34:55,889 [DEBUG] root:                                      

当前实现代码

class Downloader:
    def __init__(self, shelf_data) -> None:
        shelf = ShelfData(shelf_data)
        [logging.debug(f"shelf['{key}']: {val}") for key, val in shelf.__dict__.items()]

当前日志文件输出

2024-02-13 16:29:18,024 [DEBUG] root: shelf['shelf_name']: test_shelf
2024-02-13 16:29:18,024 [DEBUG] root: shelf['url']: https://site/group/show/1865-scifi-and-fantasy-book-club
2024-02-13 16:29:18,024 [DEBUG] root: shelf['base_path']: C:\MyProjects\downloads
2024-02-13 16:29:18,024 [DEBUG] root: shelf['creation_date']: 02/12/2024
2024-02-13 16:29:18,039 [DEBUG] root: shelf['sort_order']: descend
2024-02-13 16:29:18,039 [DEBUG] root: shelf['books_per_page']: 100
2024-02-13 16:29:18,039 [DEBUG] root: shelf['download_dir']: None
2024-02-13 16:29:18,039 [DEBUG] root: shelf['book_count']: 37095
2024-02-13 16:29:18,039 [DEBUG] root: shelf['page_count']: 371

当前日志配置

import logging.config
import os

logging_config = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default_handler': {
            'class': 'logging.FileHandler',
            'level': 'DEBUG',
            'formatter': 'standard',
            'filename': os.path.join('logs', f'{log_name}.log'),
            'encoding': 'utf-8'
        },
        'stream_handler': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'standard',}
    },
    'loggers': {
        '': {
            'handlers': ['default_handler', 'stream_handler'],
            'level': 'DEBUG',
            'propagate': False
        }
    }
}
logging.config.dictConfig(logging_config)

现成实现方案

方案1:直接构造格式化后的多行消息

无需修改日志配置,在日志调用时手动把字典拼接成符合格式的多行字符串:

class Downloader:
    def __init__(self, shelf_data) -> None:
        shelf = ShelfData(shelf_data)
        lines = []
        for key, val in shelf.__dict__.items():
            # 给字符串值自动添加引号,非字符串保持原样
            formatted_val = repr(val) if isinstance(val, str) else val
            lines.append(f"{key} = {formatted_val}")
        
        # 计算日志前缀长度,用缩进对齐后续行
        prefix_length = len("2024-02-13 13:27:03,685 [DEBUG] root: ")
        indent = ' ' * prefix_length
        
        # 拼接成最终消息
        if lines:
            message = ',\n'.join([lines[0]] + [indent + line for line in lines[1:]])
        else:
            message = ''
        logging.debug(message)

方案2:用标准库pprint格式化字典

利用Python自带的pprint模块快速格式化字典,再调整缩进匹配日志前缀:

import pprint

class Downloader:
    def __init__(self, shelf_data) -> None:
        shelf = ShelfData(shelf_data)
        # 用pprint生成格式化后的字符串
        formatted_dict = pprint.pformat(shelf.__dict__, indent=4)
        # 替换换行符,添加对应缩进
        prefix_length = len("2024-02-13 13:27:03,685 [DEBUG] root: ")
        indent = ' ' * prefix_length
        formatted_message = formatted_dict.replace('\n', '\n' + indent)
        logging.debug(formatted_message)

方案3:轻量自定义格式化器(全局生效)

如果希望所有字典类型的日志消息都自动格式化,可以自定义一个格式化器继承标准类:

import logging

class DictFormatter(logging.Formatter):
    def format(self, record):
        # 检测消息是否为字典,是则格式化
        if isinstance(record.msg, dict):
            prefix_length = len("2024-02-13 13:27:03,685 [DEBUG] root: ")
            indent = ' ' * prefix_length
            lines = []
            for key, val in record.msg.items():
                lines.append(f"{key} = {repr(val)}")
            record.msg = ',\n'.join([lines[0]] + [indent + line for line in lines[1:]]) if lines else ''
        return super().format(record)

修改日志配置,替换原有的格式化器:

logging_config = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'dict_formatter': {
            '()': DictFormatter,  # 指定自定义格式化器类
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default_handler': {
            'class': 'logging.FileHandler',
            'level': 'DEBUG',
            'formatter': 'dict_formatter',
            'filename': os.path.join('logs', f'{log_name}.log'),
            'encoding': 'utf-8'
        },
        'stream_handler': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'dict_formatter',}
    },
    'loggers': {
        '': {
            'handlers': ['default_handler', 'stream_handler'],
            'level': 'DEBUG',
            'propagate': False
        }
    }
}

使用时直接传入字典即可:

class Downloader:
    def __init__(self, shelf_data) -> None:
        shelf = ShelfData(shelf_data)
        logging.debug(shelf.__dict__)

内容的提问来源于stack exchange,提问作者Meghan M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:11:01