17 pprint美化打印
调试的时候,你用print()打印一个嵌套很深的字典或列表,输出全挤成一团,根本看不清。pprint(pretty print)就是来解决这个问题的,它会自动格式化输出,让数据结构一目了然。
一、基本用法
1.1 pprint()
python
from pprint import pprint
data = {
"users": [
{"name": "大志", "age": 28, "skills": ["Python", "LangChain", "Agent"]},
{"name": "小明", "age": 25, "skills": ["Java", "Spring", "MySQL"]}
],
"config": {
"database": {"host": "localhost", "port": 5432},
"cache": {"enabled": True, "ttl": 3600}
}
}
# 普通print
print(data)
# {'users': [{'name': '大志', 'age': 28, 'skills': ['Python', 'LangChain', 'Agent']}, {'name': '小明', 'age': 25, 'skills': ['Java', 'Spring', 'MySQL']}], 'config': {'database': {'host': 'localhost', 'port': 5432}, 'cache': {'enabled': True, 'ttl': 3600}}}
# pprint
pprint(data)
# {'config': {'cache': {'enabled': True, 'ttl': 3600},
# 'database': {'host': 'localhost', 'port': 5432}},
# 'users': [{'age': 28,
# 'name': '大志',
# 'skills': ['Python', 'LangChain', 'Agent']},
# {'age': 25,
# 'name': '小明',
# 'skills': ['Java', 'Spring', 'MySQL']}]}二、pprint vs pp
2.1 pp()(3.14+推荐)
python
from pprint import pp, pprint
data = {"a": 1, "b": [2, 3, 4]}
# pp():sort_dicts默认为False(保持原始顺序)
pp(data)
# {'a': 1, 'b': [2, 3, 4]}
# pprint():sort_dicts默认为True(按键排序)
pprint(data)
# {'a': 1, 'b': [2, 3, 4]}区别在于pp()保持字典原始顺序,pprint()默认按键排序。
三、格式化参数
3.1 indent:缩进
python
from pprint import pprint
data = {"a": {"b": {"c": 1}}}
pprint(data, indent=1) # 默认
# {'a': {'b': {'c': 1}}}
pprint(data, indent=4)
# { 'a': { 'b': { 'c': 1}}}3.2 width:行宽
python
from pprint import pprint
data = list(range(20))
# 默认宽度80
pprint(data, width=80)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
# 窄宽度,会换行
pprint(data, width=30)
# [0,
# 1,
# 2,
# ...]3.3 depth:深度限制
python
from pprint import pprint
data = {"a": {"b": {"c": {"d": {"e": 1}}}}}
# 只显示2层
pprint(data, depth=2)
# {'a': {'b': {...}}}
# 只显示3层
pprint(data, depth=3)
# {'a': {'b': {'c': {...}}}}3.4 sort_dicts:字典排序
python
from pprint import pprint, pp
data = {"c": 3, "a": 1, "b": 2}
# pp():不排序(3.14+推荐)
pp(data)
# {'c': 3, 'a': 1, 'b': 2}
# pprint():排序(向后兼容)
pprint(data)
# {'a': 1, 'b': 2, 'c': 3}
# 强制不排序
pprint(data, sort_dicts=False)四、pformat():获取字符串
python
from pprint import pformat
data = {"name": "大志", "scores": [90, 85, 92]}
# 返回格式化字符串
formatted = pformat(data)
print(formatted)
# 可以用于日志
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug(f"数据: {pformat(data)}")五、PrettyPrinter类
python
from pprint import PrettyPrinter
# 创建自定义的PrettyPrinter
pp = PrettyPrinter(indent=2, width=60, depth=3)
data = {"a": {"b": {"c": {"d": 1}}}}
pp.pprint(data)六、辅助函数
6.1 isreadable() / isrecursive()
python
from pprint import pprint
# 检查是否可读
pprint.isreadable([1, 2, 3]) # True
pprint.isrecursive([1, 2, 3]) # False
# 循环引用
data = [1, 2]
data.append(data)
pprint.isrecursive(data) # True
pprint.isreadable(data) # False6.2 saferepr()
安全的repr,处理循环引用。
python
from pprint import saferepr
data = [1, 2]
data.append(data)
# repr会报错
# repr(data) # RecursionError
# saferepr会用...代替循环引用
print(saferepr(data))
# [1, 2, <Recursion on list with id=...>]七、实用场景
7.1 调试API响应
python
from pprint import pprint
import json
response = {
"code": 200,
"data": {
"users": [
{"id": 1, "name": "大志", "roles": ["admin", "user"]},
{"id": 2, "name": "小明", "roles": ["user"]}
],
"total": 2,
"page": 1
},
"message": "success"
}
pprint(response)7.2 查看复杂对象
python
from pprint import pprint
# 查看模块的所有属性
import os
pprint(dir(os))
# 查看对象的__dict__
class MyClass:
def __init__(self):
self.x = 1
self.y = [2, 3]
self.z = {"a": 4}
obj = MyClass()
pprint(vars(obj))
# {'x': 1, 'y': [2, 3], 'z': {'a': 4}}7.3 格式化日志
python
from pprint import pformat
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def log_config(config):
logger.debug(f"配置:\n{pformat(config)}")
config = {"db": {"host": "localhost"}, "cache": {"ttl": 3600}}
log_config(config)八、与print对比
| 特性 | pprint | |
|---|---|---|
| 输出格式 | 单行 | 多行缩进 |
| 可读性 | 差 | 好 |
| 字典排序 | 不排序 | 默认排序 |
| 深度限制 | 无 | 支持 |
| 循环引用 | 报错 | 用...代替 |
九、总结
pprint模块的核心:
| 函数 | 用途 |
|---|---|
pprint() | 美化打印(向后兼容) |
pp() | 美化打印(3.14+推荐) |
pformat() | 返回格式化字符串 |
PrettyPrinter | 自定义打印器 |
调试的时候,把print()换成pprint(),数据结构立刻清晰可见。特别是打印API响应、配置文件、嵌套数据时,pprint比print好用太多。