Python 中的 4 种作用域

Python 的作用域遵循 LEGB 规则 ,即:L → E → G → B(由内向外查找)。

一、四种作用域

作用域 英文 说明 示例
Local 局部作用域 函数内部定义的变量 def func(): x = 1
Enclosing 闭包/嵌套作用域 外层嵌套函数的变量 嵌套函数中访问外层函数的变量
Global 全局作用域 模块顶层定义的变量 脚本中 x = 1
Built-in 内置作用域 Python 内置的名称 print()len()range()

二、详细说明

1. Local(局部作用域)

函数内部定义的变量,只能在函数内部访问。

复制代码
def my_func():
    x = 10  # 局部变量
    print(x)  #  可以访问

my_func()
# print(x)  #  NameError: name 'x' is not defined

特点

  • 函数调用时创建,函数返回时销毁

  • 不同函数的局部变量互不干扰

    def func_a():
    x = 10
    return x

    def func_b():
    x = 20 # 与 func_a 的 x 不同,互不影响
    return x

    print(func_a()) # 10
    print(func_b()) # 20

2. Enclosing(闭包/嵌套作用域)

在嵌套函数中,内层函数可以访问外层函数的变量。

复制代码
def outer():
    x = 10  # enclosing 变量
    
    def inner():
        print(x)  #  可以访问外层变量
    
    inner()

outer()  # 10
修改 enclosing 变量
复制代码
def outer():
    x = 10
    
    def inner():
        nonlocal x  # 声明要修改外层变量
        x = 20
    
    inner()
    print(x)  # 20

outer()

3. Global(全局作用域)

在模块顶层定义的变量,可以在整个模块中访问。

复制代码
x = 10  # 全局变量

def my_func():
    print(x)  #  可以访问全局变量

my_func()  # 10
修改全局变量
复制代码
x = 10

def my_func():
    global x  # 声明要修改全局变量
    x = 20

my_func()
print(x)  # 20
模块级别的全局变量
复制代码
# file: config.py
MAX_SIZE = 100
DATABASE_URL = "sqlite:///db.sqlite"

# file: main.py
import config
print(config.MAX_SIZE)  # 100

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

Python 预定义的名称,在任何地方都可以直接使用。

复制代码
# 内置函数
print("Hello")
len([1, 2, 3])
range(5)

# 内置异常
ValueError
TypeError

# 内置常量
True
False
None
查看所有内置名称
复制代码
print(dir(__builtins__))
# ['ArithmeticError', 'AssertionError', 'BaseException', ...]

三、作用域规则

1. 变量查找顺序(LEGB)

复制代码
x = "global"  # Global

def outer():
    x = "enclosing"  # Enclosing
    
    def inner():
        x = "local"  # Local
        print(x)     # 输出: local(先找到 Local)
    
    inner()

outer()  # local

2. 逐级查找过程

复制代码
x = "global"

def outer():
    x = "enclosing"
    
    def inner():
        # 1. 先查 Local → 没有 x
        # 2. 再查 Enclosing → 有 x = "enclosing"
        # 3. 不会继续往上查
        print(x)  # 输出: enclosing
    
    inner()

outer()

3. 不同作用域同名变量的遮蔽

复制代码
x = "global"      # Global

def outer():
    x = "enclosing"   # Enclosing(遮蔽 Global)
    
    def inner():
        x = "local"   # Local(遮蔽 Enclosing)
        print(x)
    
    inner()
    print(x)  # enclosing

outer()
print(x)  # global

四、作用域相关关键字

1. global 关键字

用于在函数内部修改全局变量。

复制代码
count = 0

def increment():
    global count  # 声明 count 是全局变量
    count += 1

increment()
print(count)  # 1

2. nonlocal 关键字

用于在嵌套函数中修改外层函数的变量。

复制代码
def outer():
    x = 10
    
    def inner():
        nonlocal x  # 声明 x 是外层变量
        x = 20
    
    inner()
    print(x)  # 20

outer()

3. 常见错误:忘记声明

复制代码
x = 10

def func():
    # 错误!这会在局部作用域创建新变量,不会修改全局变量
    x = 20  # 这是局部变量,不是修改全局

func()
print(x)  # 10(全局变量未被修改)

x = 10

def func():
    global x  # 正确
    x = 20

func()
print(x)  # 20

五、作用域与数据类型

1. 可变对象的修改不需要 global

复制代码
my_list = [1, 2, 3]

def append_item():
    # 修改列表内容,不需要 global
    my_list.append(4)

append_item()
print(my_list)  # [1, 2, 3, 4]

# 但如果要重新赋值,就需要 global
def reassign():
    global my_list
    my_list = [5, 6, 7]  # 重新赋值

2. 不可变对象必须用 global

复制代码
count = 0

def increment():
    global count
    count += 1  # 整数是不可变对象,需要重新赋值

六、注意事项

1. 条件语句不创建作用域

复制代码
if True:
    x = 10  # 即使缩进,x 还是在全局作用域

print(x)  # 10(不是错误!)

for i in range(5):
    pass

print(i)  # 4(循环变量会泄露到外层)

七、对比表

作用域 位置 访问方式 修改关键字
Local 函数内部 直接访问 -
Enclosing 外层嵌套函数 直接访问(读) nonlocal(写)
Global 模块顶层 直接访问(读) global(写)
Built-in Python 内置 直接访问 不能修改

查找顺序

LEGB:Local → Enclosing → Global → Built-in

修改规则

读变量,按 LEGB 找;写变量,默认只在 Local 改。

想改外层用 nonlocal,想改全局用 global。

核心点

  1. Python 使用 静态作用域(词法作用域)

  2. 变量赋值默认在当前作用域创建/修改

  3. 访问变量按 LEGB 顺序查找

  4. globalnonlocal 用于修改外层变量

  5. 循环、条件语句不创建新作用域

相关推荐
天才测试猿16 分钟前
2026软件测试面试八股文(含答案+文档)
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
张小凡vip1 小时前
python--爬虫--成熟的爬虫框架Scrapy
爬虫·python·scrapy
Pluchon1 小时前
Java个人综合项目——萌部落社区V2.0
java·python·spring·spring cloud·postman·idea
不瘦80斤不改名2 小时前
01-vibe-coding-起源与本质
人工智能·python
夜雪一千2 小时前
如何对新闻数据进行模糊去重
python
oyguyteggytrrwwwrt4 小时前
3dgs渲染部分详细注释
python
天天爱吃肉82186 小时前
【重磅发布:拿下新超仁达代理权 】
大数据·人工智能·python·功能测试·汽车
神王宝宝 王者小学6 小时前
面向领域驱动架构的查询实现方式
前端·python·架构
ningmengjing_7 小时前
Redis 从入门到实战:Python操作全攻略
数据库·redis·python
️学习的小王8 小时前
智能文档助手:基于RAG的本地化文档问答系统实战指南
人工智能·python·机器学习