Python编程实战 - 函数与模块化编程 - 局部变量与全局变量

在学习函数时,我们经常会遇到一个经典问题:同名变量在函数内外是否互相影响? 这其实就涉及到 Python 中的"变量作用域(Variable Scope)"。 理解作用域是掌握函数运行机制的重要一步,它决定了变量的"可见性"和"生命周期"。

本节我们将详细讲解 局部变量与全局变量 的区别、作用范围,以及如何在函数中正确地使用它们。


一、变量的作用域(Scope)

作用域(Scope) 指的是变量在程序中可访问的范围。 在 Python 中,变量的作用域主要分为两类:

  • 局部变量(Local Variable):在函数内部定义,只能在函数内部使用。
  • 全局变量(Global Variable):在函数外部定义,可以在整个程序中使用。

二、局部变量

局部变量是在函数内部创建的变量,仅在函数执行期间有效。 当函数执行结束后,局部变量就会被销毁。

python 复制代码
def show_message():
    message = "Hello from function"
    print(message)

show_message()
# print(message)  # 报错:NameError: name 'message' is not defined

解析:

  • message 是函数内部定义的变量;
  • 它在 show_message() 内有效;
  • 函数执行完毕后,message 不再存在。

三、全局变量

全局变量是在函数外部定义的变量,可以被函数内部访问(但不能直接修改)。

python 复制代码
name = "Tom"

def greet():
    print(f"你好,{name}")

greet()  # 你好,Tom

解析:

  • 变量 name 定义在函数外,是全局变量;
  • 函数内部可以直接读取它的值;
  • 但如果在函数内试图重新赋值同名变量,会创建一个新的"局部变量"。

四、局部变量与全局变量同名时

当函数中出现与全局变量同名的变量时,Python 会优先使用函数内的局部变量。

python 复制代码
x = 10

def test():
    x = 5
    print("函数内x =", x)

test()
print("函数外x =", x)

输出:

ini 复制代码
函数内x = 5
函数外x = 10

结论: 局部变量会屏蔽同名的全局变量,仅在函数内生效。


五、如何在函数中修改全局变量

默认情况下,函数内不能直接修改全局变量的值。 如果希望在函数内部修改全局变量,必须使用 global 关键字声明。

python 复制代码
count = 0

def add():
    global count  # 声明使用全局变量
    count += 1

for _ in range(3):
    add()

print("count =", count)

输出:

ini 复制代码
count = 3

注意事项:

  • 使用 global 时要谨慎;
  • 全局变量修改过多,会让程序难以维护;
  • 在大型项目中,推荐通过函数参数与返回值传递数据,而非频繁操作全局变量。

六、嵌套函数与 nonlocal 关键字

如果函数内部还有一个嵌套函数(函数中定义函数),那么还会出现 闭包变量(Enclosed Variable) 的情况。 此时可使用 nonlocal 关键字修改外层函数的变量。

python 复制代码
def outer():
    x = 10
    def inner():
        nonlocal x
        x += 5
        print("inner中x =", x)
    inner()
    print("outer中x =", x)

outer()

输出:

ini 复制代码
inner中x = 15
outer中x = 15

解释:

  • nonlocal 用于修改外层函数作用域中的变量;
  • 如果不用 nonlocal,则 x += 5 会新建一个局部变量,不影响外层 x

七、作用域规则:LEGB 原则

Python 的变量查找顺序遵循 LEGB 原则:

级别 全称 含义
L Local 局部作用域(函数内部)
E Enclosing 外层函数的作用域(嵌套函数)
G Global 全局作用域(模块级)
B Built-in 内置作用域(Python自带函数)

当访问变量时,Python 会按顺序从 L → E → G → B 查找,一旦找到就停止。

示例:

python 复制代码
x = "Global"

def outer():
    x = "Enclosing"
    def inner():
        x = "Local"
        print(x)
    inner()

outer()

输出:

sql 复制代码
Local

因为 x 在局部作用域(L)中找到了,所以不会再继续往外层查找。


八、实战案例:计数器函数

我们用一个例子来综合演示局部变量、全局变量和 nonlocal 的用法。

python 复制代码
def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

c = make_counter()
print(c())  # 1
print(c())  # 2
print(c())  # 3

解析:

  • count 是外层函数的局部变量;
  • nonlocal 让内部函数 counter() 修改它;
  • make_counter() 返回的函数形成了"闭包";
  • 每次调用 c() 时,count 都能保持状态。

九、总结

分类 定义位置 生效范围 生命周期
局部变量 函数内部 仅函数内有效 函数结束后销毁
全局变量 函数外部 整个程序有效 程序运行期间一直存在
nonlocal 变量 外层函数作用域 内外层函数共享 外层函数存在期间

十、编程建议

  • 优先使用局部变量,减少全局变量依赖;
  • 避免同名变量混用,提高可读性;
  • 仅在必要时使用 global 或 nonlocal
  • 通过参数与返回值传递数据,让函数更独立、更易测试。

结语: 掌握局部变量与全局变量,是理解 Python 函数运行机制的重要基础。 当你真正理解了作用域规则(LEGB),你就能写出更高质量、更安全的代码。

相关推荐
摇滚侠6 小时前
Spring Boot3零基础教程,KafkaTemplate 发送消息,笔记77
java·spring boot·笔记·后端·kafka
jiuri_12158 小时前
Docker使用详解:在ARM64嵌入式环境部署Python应用
python·docker·容器
chenchihwen8 小时前
AI代码开发宝库系列:Function Call
人工智能·python·1024程序员节·dashscope
计算机学长felix9 小时前
基于SpringBoot的“面向校园的助力跑腿系统”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端
紫荆鱼10 小时前
设计模式-迭代器模式(Iterator)
c++·后端·设计模式·迭代器模式
汤姆yu10 小时前
基于python的化妆品销售分析系统
开发语言·python·化妆品销售分析
RainSky_10 小时前
LNMP 一键安装包部署 Django 项目
后端·django·1024程序员节
追逐时光者10 小时前
一个开源免费、轻量级的 Avalonia UI 控件库
后端·.net