LEGB 不是“面向过程的作用域”,而是“词法作用域(Lexical Scope)”;而面向对象使用的不是作用域,而是“属性查找机制(Attribute Resolution)”。
一、 核心对比:词法作用域 (LEGB) vs 面向对象查找 (MRO)
你可以把 Python 看作一个拥有“两套户籍系统”的国家:
1. LEGB:认“代码位置”(静态的词法作用域)
inner 写在函数 outer 里面,outer 就是它的老家。不管这个函数将来被传递到哪里执行,它找变量永远只回“代码里的老家”找。2. OOP 属性查找:认“对象血缘”(动态的对象图查找)
self.x 时,Python 根本不关心这行代码写在哪个文件、哪个类里,它只关心运行时 self 到底是个什么类型的对象,然后顺着这个对象的继承链(MRO)去一层层找。如果面向对象(OOP)也使用 LEGB(词法作用域)来查找属性,面向对象最核心的灵魂——“多态(Polymorphism)”将彻底灰飞烟灭!
灾难发生:如果 speak 里的 sound 走 LEGB 作用域
speak 方法在代码文本上,是定义在 Animal 类里面的。speak 的“老家”是 Animal 的代码块。dog.speak() 执行时,它去老家找 sound,永远只会找到 Animal.sound(打印 "...")。拯救世界:使用 OOP 属性查找(self.sound)
print(self.sound)。self 是一个 Dog 实例。Dog 的 __dict__ 里找,找到了 "汪汪汪"。结论:LEGB 是“死”的(绑定在代码文本上),而 OOP 必须是“活”的(绑定在运行时的对象上)。