Python 变量作用域详解:局部、全局与模块导入
本文深入解析 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(相当于函数)的内容不再赘述。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













