Python 变量作用域详解:局部、全局与模块导入

拾柒
拾柒
发布时间:2026-10-13 | 2人浏览过
原创

本文深入解析 Python 中局部变量、全局变量及模块导入变量的作用域机制。通过代码示例演示局部变量对全局变量的隔离性,讲解如何使用 global 关键字修改全局变量,并探讨通过模块导入共享全局变量的最佳实践与潜在风险。

在 Python 中,定义在函数内部的变量仅具有局部作用域,而在模块最高层级定义的变量则具有全局作用域。本文旨在详细阐述全局变量、局部变量以及通过模块导入的全局变量的定义与使用方式。

参考来源:《Python核心编程 (第二版)》

一、局部变量

声明适用的程序范围被称为声明的作用域。在某个过程或函数中,如果变量名在声明范围内出现,它即为该过程的局部变量;否则,其出现被视为非局部变量。示例代码如下:

def foo(x): 
 print 'x = ',x 
 x = 200 
 print 'Changed in foo(), x = ',x 
x = 100 
foo(x) 
print 'x = ',x 

运行上述代码的输出结果如下:

>>> 
x = 100 
Changed in foo(), x = 200 
x = 100 

在主程序块中定义了变量 x=100,Python 通过函数声明的形参将 x 传递至 foo() 函数。在 foo() 函数内部,将 x 重新赋值为 200,此时 x 成为函数的局部变量。因此,在函数内部对 x 值的修改不会影响主块中定义的 x 值。

核心笔记:

当 Python 搜索一个标识符时,会先从局部作用域开始查找。如果在局部作用域中未找到该名称,则会在全局作用域中查找该变量;若仍未找到,则会抛出 NameError 异常。

作用域的概念与用于查找变量的名称空间搜索顺序密切相关。当一个函数执行时,所有位于局部命名空间中的名称都处于局部作用域内;在查找变量时,首先搜索的名称空间若未找到该变量,则可能找到同名的局部变量。

二、全局变量

全局变量的一个显著特征是,除非被删除,否则它们将存活至脚本运行结束,且所有函数均可访问其值。相比之下,局部变量类似于栈结构,仅暂时存在,其生命周期依赖于定义它们的函数当前是否处于活动状态。当函数调用发生时,其局部变量进入声明它们的作用域;此时,为该对象创建一个新的局部变量名;一旦函数执行完毕,框架被释放,变量随即离开作用域。

X = 100 
def foo(): 
 global X 
 print 'foo() x = ',X 
 X = X + 5 
 print 'Changed in foo(), x = ',X 
def fun(): 
 global X 
 print 'fun() x = ',X 
 X = X + 1 
 print 'Changed in fun(), x = ',X 
if __name__ == '__main__': 
 foo() 
 fun() 
 print 'Result x = ',X 

相关代码的输出结果如下:

>>> 
foo() x = 100 
Changed in foo(), x = 105 
fun() x = 105 
Changed in fun(), x = 106 
Result x = 106 

核心笔记:

使用 global 语句来定义或修改全局变量。当在函数内使用与全局变量同名的局部变量时需格外小心,如果将全局变量的名字声明在一个函数体内,全局变量的名字可能被局部变量覆盖。因此,建议尽量添加 global 语句,否则程序的读者可能无法清楚该变量是在何处定义的。

你可以使用同一个 global 语句指定多个全局变量,例如:global x, y, z。

在制作 Python 爬虫时,若需向函数中传递 url 并循环爬取每个 url 页面的 InfoBox,文件写入操作可通过两种方法实现:1. 通过传递参数 file;2. 通过定义全局变量 file。

SOURCE = open("F:\\test.txt",'w') 
def writeInfo(i): 
 global SOURCE 
 SOURCE.write('number'+str(i)+'\n') 
def main(): 
 i=0 
 while i<50: 
 writeInfo(i) 
 print i 
 i=i+1 
 else: 
 print 'End' 
 SOURCE.close() 
main() 

PS:在此种用法中,如果在函数 writeInfo() 中不使用 global 声明全局变量 SOURCE,代码其实仍可运行,但此时 SOURCE 应被视为内部变量。由于没有初始值,直接引用会报错。Python 查找变量的顺序是:先局部变量,再全局变量。

UnboundLocalError: local variable 'SOURCE' referenced before assignment 

三、模块导入变量

主要方法是通过在 py 文件中定义好变量,然后通过 import 导入这些全局变量并使用。示例代码如下:

import global_abc 
def foo(): 
 print global_abc.GLOBAL_A 
 print global_abc.GLOBAL_B 
 print global_abc.GLOBAL_C 
 global_abc.GLOBAL_C = global_abc.GLOBAL_C + 200 
 print global_abc.GLOBAL_C 
 
if __name__ == '__main__': 
 foo() 
 print global_abc.GLOBAL_A + ' ' + global_abc.GLOBAL_B 
 print global_abc.GLOBAL_C 
 输出如下所示,全局变量结构是可以改变的。
>>> 
hello 
world 
300 
500 
hello world 
500 

截图展示如下:

PS:应尽量避免使用全局变量。不同的模块都可以自由访问全局变量,这可能导致全局变量的不可预知性。例如,若程序员甲修改了 _a 的值,而程序员乙同时使用 _a,这可能导致程序错误。此类错误往往难以发现和更正。此外,全局变量降低了函数或模块之间的通用性,因为不同的函数或模块都依赖于全局变量。同样,全局变量降低了代码的可读性,阅读者可能不清楚调用的某个变量是否为全局变量。尽管某些情况下不可避免需要使用它,但仍需谨慎。

最后关于闭包和 Lambda(相当于函数)的内容不再赘述。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持本站!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表