【转】如何美观地打印 Python 对象?

pprint 是“pretty printer”的简写,“pretty”的含义是“漂亮的、美观的”,还有表示“相当地”的程度语气,因此它的含义便是:(相当)美观的打印。

这是个相当简单却有用的模块,主要用于打印复杂的数据结构对象,例如多层嵌套的列表、元组和字典等。

先看看 print() 打印的一个例子:

mylist = ["Beautiful is better than ugly.", "Explicit is better than implicit.", "Simple is better than complex.", "Complex is better than complicated."]

print(mylist)

# 结果如下:
[‘Beautiful is better than ugly.‘, ‘Explicit is better than implicit.‘, ‘Simple is better than complex.‘, ‘Complex is better than complicated.‘]

这是一个简单的例子,全部打印在一行里。

想象一下,如果对象中的元素是多层嵌套的内容(例如复杂的 Json 数据),或者有超多的元素(例如在列表中存了很多 URL 链接),再打印出来会是怎样?

那肯定是一团糟的,不好阅读。

使用 pprint 模块的 pprint() 替代 print(),可以解决如下痛点:

  • 设置合适的行宽度,作适当的换行
  • 设置打印的缩进、层级,进行格式化打印
  • 判断对象中是否出现无限循环,并优化打印内容

1、简单使用

语法:pprint(object, stream=None, indent=1, width=80, depth=None, *,compact=False)

默认的行宽度参数为 80,当打印的字符(character)小于 80 时,pprint() 基本上等同于内置函数 print(),当字符超出时,它会作美化,进行格式化输出:

import pprint

# 打印上例的 mylist
pprint.pprint(mylist)

# 打印的元素是换行的(因为超出80字符):
[‘Beautiful is better than ugly.‘,
 ‘Explicit is better than implicit.‘,
 ‘Simple is better than complex.‘,
 ‘Complex is better than complicated.‘]

2、设置缩进为 4 个空格(默认为1)

pprint.pprint(mylist, indent=4)

[   ‘Beautiful is better than ugly.‘,
    ‘Explicit is better than implicit.‘,
    ‘Simple is better than complex.‘,
    ‘Complex is better than complicated.‘]

3、设置打印的行宽

mydict = {‘students‘: [{‘name‘:‘Tom‘, ‘age‘: 18},{‘name‘:‘Jerry‘, ‘age‘: 19}]}

pprint.pprint(mydict)

# 未超长:
{‘students‘: [{‘age‘: 18, ‘name‘: ‘Tom‘}, {‘age‘: 19, ‘name‘: ‘Jerry‘}]}

pprint.pprint(mydict, width=20)

# 超长1:
{‘students‘: [{‘age‘: 18,
               ‘name‘: ‘Tom‘},
              {‘age‘: 19,
               ‘name‘: ‘Jerry‘}]}

pprint.pprint(mydict, width=70)

# 超长2:
{‘students‘: [{‘age‘: 18, ‘name‘: ‘Tom‘},
              {‘age‘: 19, ‘name‘: ‘Jerry‘}]}

4、设置打印的层级(默认全打印)

newlist = [1, [2, [3, [4, [5]]]]]

pprint.pprint(newlist, depth=3)

# 超出的层级会用...表示
[1, [2, [3, [...]]]]

5、优化循环结构的打印

当列表或其它数据结构中出现循环引用时,要完整打印出所有内容是不可能的。

所以 print 作了简化处理,就像上例一样,只打印外层的壳,而不打印内层循环的东西。

这种处理方式是简化了,但没有指出是谁导致了循环,还容易看漏。

pprint() 方法作了改进,遇到无限循环结构时,会表示成<Recursion on typename with id=number> 的格式。

还有个 saferepr() 方法,也是这样优化,而且返回的是个字符串:

newlist = [1, 2]
newlist.insert(0, newlist)

# 列表元素指向列表自身,造成循环引用
# 直接 print 的结果是:[[...], 1, 2]

pprint.pprint(newlist)
# [<Recursion on list with id=1741283656456>, 1, 2]

pprint.saferepr(newlist)
# ‘[<Recursion on list with id=1741283656456>, 1, 2]‘

6、判断是否出现循环结构

有两个方法可以判断一个对象中是否出现无限循环:

pprint.isrecursive(newlist)
# True

pprint.isreadable(newlist)
# False

isreadable() 除了能像 isrecursive() 一样判断循环,还能判断该格式化内容是否可被 eval() 重构。

以上就是 pprint 模块的快捷入门介绍,除此之外,还有 pformat() 方法、PrettyPrinter 类,以及某些参数的使用等内容,我觉得没有大用,就不多说了。

如若感兴趣,你可查阅:

最后,还有两个小小的点:

1、用 pprint() 替换 print() 的技巧

在不考虑 print() 函数本身的参数的情况下,可以在引入 pprint 模块后,写上 “print = pprint.pprint”,令 print() 起到改头换面的效果:

import pprint
print = pprint.pprint

mylist = ["Beautiful is better than ugly.", "Explicit is better than implicit.", "Simple is better than complex.", "Complex is better than complicated."]

print(mylist)

# 可对比本文开头的例子
[‘Beautiful is better than ugly.‘,
 ‘Explicit is better than implicit.‘,
 ‘Simple is better than complex.‘,
 ‘Complex is better than complicated.‘]

2、国人开发的 beeprint

国内某位 pan 同学在 Github 开源了个beeprint,明显是对标 pprint 的。

项目地址:https://github.com/panyanyany/beeprint

它优化了字典对象的打印,对于从其它语言转过来的同学而言(例如 Java),这是个福音:

它还优化了长文本的打印,支持自定义对象的打印,看起来不错。

但是,其它功能不够齐全,而且作者停止维护两年了,荒废已久……

总体而言,pprint 算是 print() 的轻量级替代,简单实用,极其方便(毕竟是标准库),文档丰富而有保障。

所以,若想要打印美观易读的数据,这个 pprint 标准库,不妨一试哦。

原文地址:https://www.cnblogs.com/pythonista/p/11407546.html

原文地址:https://www.cnblogs.com/yuanyufei/p/11407634.html

时间: 2024-10-13 00:37:07

【转】如何美观地打印 Python 对象?的相关文章

如何美观地打印 Python 对象?这个标准库可以简单实现

前不久,我写了一篇文章回顾 Python 中 print 的发展历史 ,提到了两条发展线索: 明线:早期的 print 语句带有 C 和 Shell 的影子,是个应用程序级的 statement,在最初十几年里,经历过 PEP-214 和 PEP-259 的改进:再到 2009 年的大版本 3.0,由语句改成了 print() 函数,还在 3.3 版本,做过一次功能增强,最终上升成为一等的内置函数. 暗线:介绍了 print 的竞争对手们,像传统的日志模块 logging.调试模块 pdb.主流

《python源码剖析》笔记 python对象初探

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.      在python中,对象就是为C中的结构体在堆上申请的一块内存.对象不能被静态初始化,也不能在栈空间生存.但内建的类型对象都是被静态初始化的. 2.      对象创建后大小不变.可变对象有一指针指向可变大小的内存区域. 3.      对象机制的基石:PyObject 定长对象: typedef struct _object{ PyObject_HEAD }PyObject

pickle和cPickle:Python对象的序列化

目的:Python对象序列化 可用性:pickle至少1.4版本,cPickle 1.5版本以上 pickle模块实现了一种算法,将任意一个Python对象转化成一系列字节(byets).此过程也调用了serializing对象.代表对象的字节流之后可以被传输或存储,再重构后创建一个拥有相同特征(the same characteristics)的新的对象. cPickle使用C而不是Python,实现了相同的算法.这比Python实现要快好几倍,但是它不允许用户从Pickle派生子类.如果子类

Python学习笔记(四)Python对象

1,Pythons对象特点 从更具体的视角看,Python程序可分解成模块.语句.表达式和对象.程序由模块组成,模块包含语句,语句包含表达式而表达式建立并处理对象.Python提供了强大的对象类型作为语言的组成部分,除非有内置类型无法处理得特殊对象,用户最好总是使用内置对象.Python内置对象类型强大而高效,是一个python程序的核心部分,让编程变得简单.使用内置对象的优点是: (1)使编程更容易-内置对象往往可以表现问题领域的所有结果,还可以马上使用集合.搜索表等强大的工具,仅使用内置对象

Python对象、数据类型总结

Python在定义变量时不用注明数据类型(与java不同) 例1:>>a=10 >>print type(a) # 打印类型 <type 'int'> # 可以自动识别数据类型(对于数字,识别数字类型int) 例2:>>b='love' >>print type(b) <type 'str'> # 识别数据类型str Python对象包含三个基本要素: id(身份标识).type(数据类型).value(值) 例:>> a

01.python对象

标准类型 数字 Integer 整型 Boolean 布尔型 Long integer 长整型 (python2) Floating point real number 浮点型 Complex number 复数型 String 字符串 List 列表 Tuple 元组 Dictionary 字典 其他内建类型 类型 Null对象(None) 集合/固定集合 函数/方法 模块 类 类型对象和type类型对象 调用内建函数type(),能够得到特定对象的类型信息 # 11是个int型对象>>&g

Python对象剖析

Python是面向对象语言,在Python世界中,一切皆是对象,一个整数是一个对象,一个字符串也是一个对象.更奇妙的是,类型也是一个对象,在Python虚拟机(解释器)执行代码过程中,也会生成许多对象,包括一个模块.代码块.函数等. 一.Python对象分类 Python对象在概念上可以分为5类. Fundamental对象:类型对象 Numeric对象:数值对象 Sequence对象:容纳其他对象的序列集合对象 Mapping对象:映射(关联)对象 Internal对象:Python虚拟机在运

python对象序列化或持久化的方法

http://blog.csdn.net/chen_lovelotus/article/details/7233293 一.Python对象持久化方法 目前为止,据我所知,在python中对象持久化有以下几种方法: 1. 使用(dbhash/bsddb, dbm, gdbm, dumbdbm 等)以及它们的"管理器"( anydbm ).只提供了 Python 字 符串的永久性储存. 提供一个类似字典和文件的对象,可以完成字符串的永久性存储. 2. 使用marshal和pickle来序

Python回顾与整理2:Python对象

0.说明 说对象是面向对象编程语言最重要的一部分一点也不为过,没有了"对象",面向对象将无从谈起.Python也是如此,如果无法掌握对象,你很难有大的进步与提升. 1.Python对象 (1)对象特性 Python使用对象模型来存储数据,构造任何类型的值都是一个对象,所有的Python对象都拥有下面的三个特性: 身份:每个对象一唯一身份标识,可使用内建函数id()查看该值(可以认为这个值是该对象的内在地址) 类型:对象的类型决定了对象(可以保存什么类型的值,进行什么样的操作,遵循什么样