Python系列教程

Python作用域详解:局部变量与全局变量

2025-10-25 7 0

简介 Python作用域详解:局部变量与全局变量

1. 什么是作用域?

作用域(Scope)指的是变量在程序中的可访问范围。Python中有四种作用域:

  • 局部作用域(Local):在函数内部

  • 嵌套作用域(Enclosing):在嵌套函数中

  • 全局作用域(Global):在模块级别

  • 内置作用域(Built-in):Python内置的变量

2. 局部变量

定义:

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

示例:

python

def my_function():
    local_var = "我在函数内部"  # 局部变量
    print(local_var)  # 可以访问

my_function()  # 输出: 我在函数内部
# print(local_var)  # 报错:NameError,在函数外部无法访问

特点:

  • 函数调用时创建,函数结束时销毁

  • 不同函数中可以定义同名局部变量,互不干扰

python

def function1():
    x = 10  # function1的局部变量
    print(f"function1中的x: {x}")

def function2():
    x = 20  # function2的局部变量
    print(f"function2中的x: {x}")

function1()  # 输出: function1中的x: 10
function2()  # 输出: function2中的x: 20

3. 全局变量

定义:

在函数外部定义的变量,在整个模块中都可以访问。

示例:

python

global_var = "我是全局变量"  # 全局变量

def function1():
    print(f"function1访问: {global_var}")

def function2():
    print(f"function2访问: {global_var}")

function1()  # 输出: function1访问: 我是全局变量
function2()  # 输出: function2访问: 我是全局变量
print(f"外部访问: {global_var}")  # 输出: 外部访问: 我是全局变量

4. 关键问题:在函数内部修改全局变量

情况1:直接修改(会报错)

python

count = 0  # 全局变量

def increment():
    count = count + 1  # 报错!Python认为count是局部变量

# increment()  # UnboundLocalError: local variable 'count' referenced before assignment

情况2:使用 global 关键字

python

count = 0  # 全局变量

def increment():
    global count  # 声明要使用全局变量count
    count = count + 1
    print(f"函数内部: {count}")

print(f"调用前: {count}")  # 输出: 调用前: 0
increment()               # 输出: 函数内部: 1
print(f"调用后: {count}")  # 输出: 调用后: 1

5. 变量查找顺序(LEGB规则)

Python按照以下顺序查找变量:

  1. Local - 局部作用域

  2. Enclosing - 嵌套作用域

  3. Global - 全局作用域

  4. Built-in - 内置作用域

python

x = "global"  # 全局变量

def outer():
    x = "enclosing"  # 嵌套作用域变量
    
    def inner():
        x = "local"  # 局部变量
        print(f"内部函数: {x}")
    
    inner()
    print(f"外部函数: {x}")

outer()
print(f"模块级别: {x}")

输出:

text

内部函数: local
外部函数: enclosing
模块级别: global

6. 常见场景分析

场景1:列表和字典的特殊性

python

# 对于可变对象(列表、字典等),在函数内部可以直接修改内容
my_list = [1, 2, 3]  # 全局变量

def modify_list():
    my_list.append(4)  # 可以直接修改,不需要global
    my_list[0] = 100   # 可以直接修改元素

print(f"修改前: {my_list}")  # 输出: 修改前: [1, 2, 3]
modify_list()
print(f"修改后: {my_list}")  # 输出: 修改后: [100, 2, 3, 4]

# 但是如果要重新赋值,就需要global
def reassign_list():
    global my_list
    my_list = ["全新列表"]  # 重新赋值

reassign_list()
print(f"重新赋值后: {my_list}")  # 输出: 重新赋值后: ['全新列表']

场景2:嵌套函数中的变量

python

def outer():
    x = "outer"  # 嵌套作用域变量
    
    def inner():
        nonlocal x  # 使用nonlocal修改嵌套作用域的变量
        x = "modified by inner"
        print(f"inner: {x}")
    
    print(f"调用inner前: {x}")  # 输出: 调用inner前: outer
    inner()
    print(f"调用inner后: {x}")  # 输出: 调用inner后: modified by inner

outer()

7. 最佳实践建议

✅ 推荐做法:

python

# 使用参数传递和返回值
def process_data(data):
    result = data * 2  # 使用局部变量
    return result

global_data = 10
processed = process_data(global_data)
print(processed)  # 输出: 20

❌ 避免的做法:

python

# 避免过度使用全局变量
global_var = 0

def bad_design():
    global global_var
    global_var += 1
    # 这样会使函数依赖外部状态,难以测试和维护

8. 综合练习

python

# 全局变量
total = 0
items = []

def add_item(name, price):
    global total
    items.append(name)      # 直接修改全局列表
    total += price          # 修改全局变量需要global声明
    local_tax = price * 0.1  # 局部变量
    
    def calculate_discount():
        nonlocal local_tax  # 修改嵌套作用域变量
        local_tax = local_tax * 0.9
        return local_tax
    
    discount = calculate_discount()
    return discount

# 测试
print(f"初始总额: {total}")  # 输出: 初始总额: 0
tax = add_item("书本", 100)
print(f"商品列表: {items}")   # 输出: 商品列表: ['书本']
print(f"当前总额: {total}")   # 输出: 当前总额: 100
print(f"计算税费: {tax}")     # 输出: 计算税费: 9.0

9. 总结

关键字作用使用场景
无声明创建局部变量函数内部定义新变量
global使用全局变量在函数内部修改全局变量
nonlocal使用嵌套作用域变量在嵌套函数中修改外部函数变量

记住这个简单的原则:当你不确定时,尽量使用局部变量,通过参数和返回值来传递数据,这样代码更清晰、更容易维护。


点赞 0

我的名片

网名:梦宇信息技术

职业:软件开发、Mes系统工程师

现居:福建省-福州市

QQ:703159

站点信息

  • 联系QQ:703159
  • 文章统计120篇文章
  • 标签总数6
  • 加我微信:扫码,加我微信