Python 中的 Legb 规则

2024 年 8 月 29 日 | 阅读 3 分钟

Python 的 LEGB 规则,顾名思义,用于 Python 解析名称。下面是对这些短语的简要解释:

  • 任何 Python 函数和 lambda 表达式的代码块和函数体都属于局部(或函数)作用域。我们在函数内部提供的名称都包含在此 Python 作用域中。只有函数内的代码才能访问这些名称。由于局部作用域是在函数调用时创建的,而不是在函数定义时创建的,因此每次函数调用都会产生一个独立的局部作用域。每次调用都会导致创建一个新的局部作用域。
  • 只有嵌套函数才具有封闭(或非局部)作用域,这是一个独特的作用域。我们在封闭函数中定义的变量包含在此作用域中。内部函数和封闭函数的代码会显示封闭作用域内的名称。
  • Python 程序、脚本或模块的最高级别作用域是全局(或模块)作用域。我们在程序或模块的顶层定义的所有变量都包含在此 Python 作用域中。我们代码的所有部分都可以访问此 Python 作用域中的名称。
  • 每次运行脚本或启动交互式会话时,都会生成或加载一个名为“内置作用域”的独特 Python 作用域。此作用域包括内置 Python 术语的名称,如关键字、函数、异常以及其他属性。此 Python 作用域中的名称也可以在我们的代码中访问。每当我们启动程序或脚本时,Python 都会自动加载它。

LEGB 规则在 Python 查找名称时控制查找方式,这是一种名称查找操作。

总之,当我们在使用嵌套函数时,Python 会首先检查局部作用域或最内层函数的局部作用域来解析名称。然后,Python 会从最深层作用域到最外层作用域,检查所有外部函数的封闭作用域。如果找不到匹配项,Python 随后会检查全局作用域和内置作用域。如果找不到该名称,我们将收到一个警告。

根据代码执行时的位置,最多只会存在四种活动的 Python 作用域:局部、封闭、全局和内置。然而,全局和内置作用域始终是两种活跃的作用域。这两种作用域始终可供我们使用。

示例 1

输出

The value of x is 8

说明

在全局命名空间中,变量 x 被定义为值 2,函数 f 被定义为一个参数,该参数打印一个字符串及其值。当调用 f 时,函数的局部命名空间将参数 a 初始化为值 8。在第 4 行,Python 首先在局部命名空间中查找 a。然后它移至最内层命名空间,并找到一个名为 a 的项,该项映射到一个值为 8 的整数。然后 Python 停止查找,并输出“a 的值是”,后跟它找到的 a 的值,“8”。

示例 2

输出

The value of a is 2

说明

第 1 行定义了全局命名空间变量 a,其值为 2。在全局命名空间中,我们在第 3 行定义了函数 f。我们在第 8 行调用 f。这会在局部命名空间(位于全局命名空间内)中创建一个函数 g 和一个值为 3 的参数 y。第 6 行调用 g,它创建了一个新的局部命名空间,参数 c 的值为 3。先前通过调用 f 创建的局部命名空间现在是一个封闭命名空间。

现在我们到了打印语句!Python 现在会在已使用的命名空间中查找名为 a 的对象。由于局部命名空间中没有类似的变量,Python 会尝试在封闭命名空间中查找。Python 在全局命名空间中查找,因为 a 也没有在那里声明。我们在那里找到了一个名为 a 的项,它对应于值为 2 的对象。因此,Python 输出“a 的值是”,然后是“2”,这是全局命名空间中 a 的值。