器→工具, 编程语言

Python美化输出工具pprint

钱魏Way · · 3 次浏览

pprint(Pretty-Printer)是Python标准库中一个用于美化输出复杂数据结构的模块,特别适用于嵌套较深或元素较多的字典、列表、元组等。相比普通的print(),它能自动格式化输出,使其更具可读性。

主要特点

  • 自动格式化:自动处理嵌套数据结构
  • 智能换行:根据宽度限制智能换行
  • 键值排序:默认对字典键排序(可配置)
  • 深度控制:可限制嵌套深度显示
  • 递归安全:安全处理循环引用

与相关工具对比

工具 优点 缺点 适用场景
pprint 支持所有Python类型,自动处理循环引用,可配置性强 性能相对较慢 调试复杂Python数据结构
json.dumps 标准JSON格式,可跨语言,性能好 只支持JSON类型,不处理循环引用 数据序列化,API响应
yaml.dump 人类可读性极好,支持复杂结构 需要额外依赖 配置文件,文档
print 简单直接,性能最好 无格式化,可读性差 简单输出,快速调试

基本对比

import pprint
import json

# 原始数据
data = {
    'users': [
        {'id': 2, 'name': 'Bob', 'roles': ['user']},
        {'id': 1, 'name': 'Alice', 'roles': ['admin', 'user']}
    ],
    'metadata': {'created': '2024-01-01', 'version': 1.0}
}

# 1. 普通 print
print("普通 print:")
print(data)
# 输出:单行,难以阅读

# 2. json.dumps
print("\njson.dumps:")
print(json.dumps(data, indent=2, sort_keys=True))
# 输出:格式化,但只能处理JSON兼容类型

# 3. pprint
print("\npprint:")
pprint.pprint(data)
# 输出:格式化,支持所有Python类型,自动处理非ASCII字符

pprint()函数

pprint.pprint(
    object,           # 要打印的对象
    stream=None,      # 输出流,默认为 sys.stdout
    indent=1,        # 每级缩进空格数
    width=80,        # 每行最大字符数
    depth=None,      # 最大嵌套深度
    *,
    compact=False,   # 紧凑模式
    sort_dicts=True, # 字典键排序
    underscore_numbers=False  # Python 3.10+: 数字使用下划线分隔
)

pformat()函数

返回格式化字符串而不直接打印

# 返回字符串,适合存储或进一步处理
formatted = pprint.pformat(data, indent=2, width=60)
print("格式化字符串:")
print(formatted)

# 可用于日志记录
import logging
logger = logging.getLogger(__name__)
logger.debug("数据:\n%s", pprint.pformat(data))

PrettyPrinter类

创建自定义打印机实例

# 创建自定义配置的打印机
pp = pprint.PrettyPrinter(
    indent=4,
    width=100,
    depth=3,
    compact=True,
    sort_dicts=False
)

# 多次使用相同配置
pp.pprint(data1)
pp.pprint(data2)

# 获取格式化字符串
str1 = pp.pformat(data1)

参数详细说明

indent- 缩进控制

data = {'a': [1, 2, 3], 'b': {'x': 10, 'y': 20}}

pprint.pprint(data, indent=2)  # 2空格缩进
# 输出:
# { 'a': [1, 2, 3],
#   'b': { 'x': 10,
#          'y': 20}}

pprint.pprint(data, indent=4)  # 4空格缩进
width- 宽度控制 
long_list = list(range(20))

# 宽度较小,频繁换行
pprint.pprint(long_list, width=30)
# 输出:
# [0,
#  1,
#  2,
#  ...]

# 宽度较大,尽量不换行
pprint.pprint(long_list, width=200)
depth- 深度限制 
nested = {
    'level1': {
        'level2': {
            'level3': {
                'level4': 'deep'
            }
        }
    }
}

# 限制深度
pprint.pprint(nested, depth=2)
# 输出:
# {'level1': {'level2': {...}}}
compact- 紧凑模式 
# 控制长序列的显示方式
long_sequence = [f"item_{i}" for i in range(20)]

# compact=False(默认)
pprint.pprint(long_sequence, width=50, compact=False)
# 每个元素单独一行

# compact=True
pprint.pprint(long_sequence, width=50, compact=True)
# 尽可能在一行显示多个元素
sort_dicts- 字典排序 
unsorted_dict = {'z': 3, 'a': 1, 'm': 2}

# 默认排序
pprint.pprint(unsorted_dict, sort_dicts=True)
# 输出:{'a': 1, 'm': 2, 'z': 3}

# 保持插入顺序
pprint.pprint(unsorted_dict, sort_dicts=False)
# 输出:{'z': 3, 'a': 1, 'm': 2}

处理特殊数据类型

# 1. 集合
data_set = {1, 2, 3, 4, 5}
pprint.pprint(data_set)  # 自动排序集合元素

# 2. 命名元组
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
pprint.pprint(p)  # 保持命名元组的表示形式

# 3. 自定义对象
class CustomClass:
    def __init__(self, value):
        self.value = value
    def __repr__(self):
        return f"CustomClass({self.value})"

obj = CustomClass(42)
pprint.pprint(obj)  # 使用__repr__方法

处理递归引用

# 创建递归数据结构
recursive_list = [1, 2, 3]
recursive_list.append(recursive_list)  # 添加对自己的引用

# 安全处理递归
pprint.pprint(recursive_list, depth=3)
# 输出:[1, 2, 3, [...]]

# 检查递归
print("是否递归:", pprint.isrecursive(recursive_list))
print("是否可读:", pprint.isreadable(recursive_list))

自定义格式化

class CustomPrettyPrinter(pprint.PrettyPrinter):
    """自定义打印机"""
    
    def format(self, obj, context, maxlevels, level):
        """重写格式化方法"""
        if isinstance(obj, set):
            # 自定义集合显示格式
            items = sorted(obj)
            return ', '.join(str(i) for i in items), True, False
        elif isinstance(obj, complex):
            # 自定义复数显示格式
            return f"{obj.real}+{obj.imag}j", True, False
        return super().format(obj, context, maxlevels, level)

# 使用自定义打印机
custom_printer = CustomPrettyPrinter(width=50)
custom_printer.pprint({1+2j, 3+4j, 5+6j})

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注