Python变量的四种作用域

在 Python 中,变量的作用域决定了它在代码中哪些位置可以被访问。根据 LEGB 规则,Python 查找变量时遵循以下四种作用域的先后顺序:

  1. L(Local)局部作用域
  2. E(Enclosing)外层函数作用域(也称闭包作用域)
  3. G(Global)全局作用域
  4. B(Built-in)内建作用域

下面逐一说明。


1. 局部作用域(Local)

  • 定义:函数内部定义的变量拥有局部作用域,只在函数体内可见。

  • 生命周期:函数调用时创建,函数返回或抛出异常时销毁。

  • 访问限制:函数外部无法直接访问局部变量。

  • 示例 :

    python 复制代码
    def func():
        x = 10      # 局部变量
        print(x)    # 可以访问
    func()
    # print(x)      # 错误:NameError,外部无法访问

2. 外层函数作用域(Enclosing)

  • 定义:出现在嵌套函数中,外层函数(包含内层函数的函数)内的变量,对于内层函数来说就是外层作用域变量。

  • 特点 :内层函数可以读取外层函数的变量,但若要修改,需要使用 nonlocal 关键字。

  • 用途:实现闭包(closure)或装饰器。

  • 示例:

    python 复制代码
    def outer():
        y = 20              # 外层作用域变量
        def inner():
            print(y)        # 内层函数可以访问 y
        inner()
    outer()

    修改外层变量:

    python 复制代码
    def outer():
        y = 20
        def inner():
            nonlocal y      # 声明要修改外层变量
            y = 30
        inner()
        print(y)            # 输出 30

3. 全局作用域(Global)

  • 定义:在模块顶层(非函数、非类内部)定义的变量,在整个模块内均可访问。

  • 访问限制 :函数内可以读取全局变量,但若要修改,必须使用 global 关键字。

  • 示例 :

    python 复制代码
    z = 100                 # 全局变量
    def foo():
        print(z)            # 可以读取
    foo()
    
    def bar():
        global z            # 声明要修改全局变量
        z = 200
    bar()
    print(z)                # 输出 200

4. 内建作用域(Built-in)

  • 定义 :Python 解释器启动时自动加载的内置命名空间,包含所有内置函数(如 print、len)、异常类(如 ValueError)、常量(如 True、False)等。

  • 位置 :builtins 模块(Python 3 中)。

  • 优先级:最低,只有在局部、外层、全局都找不到变量时,才会去内建作用域查找。

  • 示例 :

    python 复制代码
    # 即使没有定义 len,Python 也会从 builtins 中找到 len 函数
    print(len("hello"))    # 输出 5
    
    # 不建议,但可以故意覆盖内建名称
    len = 10               # 在全局作用域中覆盖了内建 len
    # print(len("abc"))    # 现在会出错,因为 len 变成了整数

LEGB 查找顺序

当在代码中使用一个变量时,Python 按照 L → E → G → B 的顺序依次查找:

  1. 先查当前函数的 局部作用域。
  2. 如果没找到,向上查任何外层函数(嵌套情况)的 外层作用域。
  3. 再没找到,查模块级别的 全局作用域。
  4. 最后查 内建作用域。
  5. 如果依然找不到,抛出 NameError。
python 复制代码
x = "global"
def outer():
    x = "enclosing"
    def inner():
        x = "local"
        print(x)      # 输出 "local"
    inner()
outer()

总结表

作用域 位置 如何修改外部变量 生命周期
局部 (L) 函数内部 无需声明,直接赋值即创建局部变量 函数调用期间
外层 (E) 嵌套函数的外层函数 使用 nonlocal 声明 外层函数调用期间
全局 (G) 模块顶层(任何函数/类外部) 使用 global 声明 模块被加载到解释器结束
内建 (B) builtins 模块 不可直接修改(覆盖会导致错误) Python 解释器运行期间始终存在

理解 LEGB 规则有助于写出清晰、无歧义的代码,并避免意外的变量遮蔽(shadowing)。

相关推荐
实心儿儿4 分钟前
Qt — Qt 多线程
开发语言·qt
happylifetree7 分钟前
Python06-08:Python开发工具PyCharm安装
python·pycharm
liuchangng15 分钟前
类Jev项目Kev从入门到实战(1):Kev 是什么——不开权重也能自训的决策模型
人工智能·python·jev·kev·决策模型
leihefeng33 分钟前
PX06-对比两个 Excel 文件的差异:从逐单元格到生产级实现
python·excel
小小龙学IT37 分钟前
Go 泛型(Generics)深度解析:从类型参数到生产实践
开发语言·数据库·golang
hold?fish:palm1 小时前
45 二叉树的右视图
开发语言·c++·算法
MI_farmer1 小时前
Anaconda 安装在 D 盘但虚拟环境跑到 C 盘,以及 Conda PermissionError: WinError 5 的解决方法
c语言·开发语言·conda
Ticnix1 小时前
MCP 上个月把自己推翻重写了:Session 没了、Sampling 废了——你学的教程还停在 2025
python·agent·全栈
“AI国潮设计-小江”1 小时前
[AIGC实战] 基于Stable Diffusion的潮汕非遗IP自动化生成工作流(附Python批量处理脚本)
开发语言·人工智能·python·prompt·aigc
LOVE️YOU1 小时前
Python 中的 range 是类还是函数?range 对象该怎么理解?
python