📄 一句话概括
过程式一 dump 就清清楚楚;OOP 的 dump 里全是对象,一行 repr 只给类名和地址,摊开要 3 行。
📝 本节和前面几节的关系
5.13 收完内存这一章,这个专栏讲当年调试这些对象有多费劲。
一、当年的处境
没有图形调试器,调试就是打印内存(dump)——把一块内存按格式摊出来看。 过程式程序一摊就是全部:全局变量、局部变量,一行一行看下去。 OOP 程序一摊全是对象:每个对象只给你一个地址,要看内容还得自己走进去。
二、实测差别
一行 repr:只给出类名和地址——User object at 0x...,一个字段都没告诉你。
要看清内容得自己递归:这个 2 层对象摊开是 3 行(name、addr、addr.city)。
层级越深,行数涨得越快——三层就是五、六行,还得自己写递归。
而全局变量一行 print(globals()) 就够了。
三、为什么费劲
数据不再平铺,而是挂在对象里,一层套一层。 这正是 5.6 说的【内存用法】的副作用:数据搬进对象之后,访问路径变长了。 所以这不是 OOP 的缺陷,是它的代价——换来的是数据有边界、有主人。
四、解法与教训
解法不是退回过程式,而是造工具:今天的调试器可以点开任意一层、可以搜索引用链。
还有一条更实用的:给类写 __repr__,让打印出来的东西有内容。
记住这一条:结构越深,越需要工具;靠眼睛看是看不动的。
五、动手 Demo:OOP 中 dump 看起来很费劲?
一个两层的对象,一行 repr 能看出什么。 再自己写个递归,看要几行才能看清。
u0 = User("甲", Addr("宜昌"))
print(repr(u0)) # 只有类名和地址
def dump(o, lvl=0, out=None):
out = [] if out is None else out
for k in sorted(vars(o)):
v = getattr(o, k)
if hasattr(v, "__dict__"):
out.append(" " * lvl + k + ":")
dump(v, lvl + 1, out)
else:
out.append(" " * lvl + k + " = " + str(v))
return out
实跑输出:
--------------------------------------------------------------------
OOP 中 dump 看起来很费劲?
--------------------------------------------------------------------
专栏【编程往事】说的是当年调试的事:**过程式程序一 dump 就清清楚楚,**
**OOP 程序的 dump 里全是对象,人和对象之间还隔着一层。**实测这个差别:
一行 repr 能看到什么:
User object at 0x...
(除了类名和地址,一个字段都没告诉你)
要看全得自己递归,实测逐层摊开:
addr:
city = 宜昌
name = 甲
这个对象摊开要几行 3 行
层级 2 层(User → Addr)
而全局变量一行就够 print(globals())
**这就是当年觉得【费劲】的原因:数据不再平铺,而是挂在对象里,一层套一层。**
**解法不是退回过程式,而是造工具**——今天的调试器可以点开任意一层。
**记住这一条:结构越深,越需要工具;靠眼睛看是看不动的。**
实测:一行 repr 只给类名和地址,一个字段都不给;自己递归摊开要 3 行(2 层)。 数据不再平铺而是挂在对象里——这就是当年觉得费劲的原因,解法是造工具而不是退回过程式。
30 秒实验
- 给你自己的类写一个
__repr__,看调试时省多少事。 - 想一想:你的项目里最深的那个对象有几层。
常见误区
- 以为 dump 费劲说明 OOP 不好。那是代价,换来的是数据有边界。
- 以为今天的调试器就不用懂结构。不懂结构,连断点该打在哪儿都不知道。
自测三问(点开对答案)
1. 当年 dump OOP 程序为什么费劲? —— 数据不再平铺而是挂在对象里,一层套一层;一行 repr 只给类名和地址,要看内容得自己递归。 2. 实测这个两层对象摊开要几行? —— 3 行:name = 甲、addr:、city = 宜昌;而全局变量一行 print(globals()) 就够。 3. 现在的解法是什么? —— 造工具:调试器可以点开任意一层、搜索引用链;另外给自己的类写 __repr__ 也很实用。- ☐ 下一章(第六章 重用:OOP带来的软件重用和思想重用)
相关笔记
- 孤立的实例由垃圾回收处理 — 正文收束
- OOP 的特征在于内存的用法 — 这个副作用的来源
- 原因之一:OOP结构复杂 — 复杂在哪一层
- 🧩 面向对象是怎样工作的 · 索引