🧩 第五章 理解内存结构:程序员的基本素养
📄 一句话概括

一行 s.area() 背后是四步:找变量、找对象、找方法、执行——每一步落在内存的不同位置。

📝 本节和前面几节的关系

第四章讲完三个结构和三条边界,这一章换个角度:这些对象在内存里到底怎么摆。

一、四步

找变量——变量里存的是一个地址,变量自己站在栈上。 找对象——顺着地址走到堆上,那块里放着它自己那份数据。 找方法——对象身上没有方法,要顺着它指向的类去找。 执行——把 self 和参数一起递进去,方法开始跑。

二、实测三个事实

类上有 area/kind;实例 a 自己只有 h/w。 type(a) is type(b) 是 True——两个实例认的是同一个类。 a.area 来自 Rect.area——方法名写在类上,不在实例上。 这三条一确认,后面十几节就都有依据了。

三、为什么先讲机制

因为后面每一条结论都从这里长出来:类信息只有一份、每次 new 占一块、变量里存地址。 不懂机制,就只能背结论;背下来的结论,遇到新语言就废了。 作者把这一章叫【程序员的基本素养】,意思是:这些不是 OOP 知识,是常识。

四、这一章的路线

5.2~5.4 讲程序怎么跑起来:编译器与解释器、虚拟机、线程。 5.5~5.13 讲内存怎么分:三个区、一份类信息、N 块堆、指针、复制、多态、配置、回收。 注意这两段是一条线:先要知道东西放在哪,才谈得上怎么用。

五、动手 Demo:理解 OOP 程序的运行机制

把一行 s.area() 拆成四步,看每一步落在哪。 再验证三件事:类上有什么、实例上有什么、方法从哪来。

class Rect:
    kind = "矩形"
    def __init__(self, w, h):
        self.w = w
        self.h = h
    def area(self):
        return self.w * self.h

a, b = Rect(6, 4), Rect(3, 3)
print(sorted(k for k in Rect.__dict__ if not k.startswith("__")))
print(sorted(a.__dict__), type(a) is type(b))
print(a.area.__qualname__)

实跑输出:

--------------------------------------------------------------------
理解 OOP 程序的运行机制
--------------------------------------------------------------------

  一行 `s.area()` 看着简单,**背后要走四步**:找变量、找对象、找方法、执行。
  每一步落在内存的不同位置——**这就是 5.5 那张三区图的前半段。**

  环节         发生了什么                             落在哪一块
  ---------------------------------------------------------------
  找变量 s     变量里存着一个地址                     栈
  找对象       按地址找到对象,它带着自己那份数据     堆
  找方法       对象自己没有方法,顺着类去找           类信息区
  执行         把 self 和参数一起递进去               栈+堆

  实测三个事实:

      类上有什么          area/kind
      a 自己有什么        h/w
      b 自己有什么        h/w
      type(a) is type(b)  True
      a.area 来自         Rect.area

  **注意看 a 自己有什么:里面没有 `area`。**
  方法不在实例上,**实例上只有数据;方法是顺着类找的。**
  **这一条决定了:造一万个实例,方法也只有一份。**

实测:类上是 area/kind,实例上只有 h/w,a.area 来自 Rect.area。 方法不在实例上——实例只存数据,方法是顺着类找的,所以一万个实例也只有一份方法代码。

30 秒实验

  1. 随便挑一个你写的方法,想一想调用它的那四步各落在哪。
  2. 用 type(x).__dict__ 和 x.__dict__ 分别看一眼,确认方法在谁那边。

常见误区

  1. 以为实例里存着方法。实例只存数据,方法在类上。
  2. 以为这些是 OOP 特有的知识。它是所有语言的常识。
自测三问(点开对答案) 1. 调用 s.area() 要走哪四步? —— 找变量(栈)、找对象(堆)、找方法(顺着类信息找)、执行(把 self 和参数递进去)。 2. 实测哪三件事确认了机制? —— 类上有 area/kind、实例上只有 h/w、a.area 来自 Rect.area——方法不在实例上。 3. 为什么把这一章叫程序员的基本素养? —— 因为这些不是 OOP 知识而是常识:不懂它就只能背结论,遇到新语言就废。

相关笔记