Python内置函数locals()与globals()深度解析:原理、差异及修改行为
本文深入解析Python中locals()与globals()两个内置函数的工作机制。通过名字空间(Name Space)概念,阐述局部、全局及内置变量的查找顺序。重点对比两者行为差异:locals()返回局部变量字典的副本,修改无效;而globals()直接返回全局变量字典,修改会实时影响全局变量。结合代码实例说明import与from...import对名字空间的影响,帮助开发者准确掌握变量作用域管理。
本文通过具体实例,详细解析Python基础教程中内置函数locals()和globals()的实际应用方法,供读者参考学习。
这两个函数的核心功能在于提供基于字典形式访问局部变量和全局变量的途径。
Python通过“名字空间”(Name Space)机制来追踪变量。名字空间本质上是一个字典,其键为字符串形式的变量名,值为变量对应的实际数据。
名字空间的行为方式与Python中的标准dictionary类型一致,支持常规访问。
在任何Python程序的执行过程中,同时存在多个可用的名字空间。
每个函数都拥有独立的局部名字空间,用于存储该函数的变量,包括传入的参数以及函数内部定义的局部变量。
每个模块拥有独立的全局名字空间,用于存储模块级别的变量,涵盖函数、类定义、导入的其他模块、模块级变量及常量。
此外还存在内置名字空间,对所有模块可见,其中存放着Python内置函数和异常类型。
当代码需要获取变量x的值时,Python会按照特定优先级在所有可用名字空间中查找该变量,顺序如下:
首先是局部名字空间,即当前函数或类的方法作用域。若函数内定义了局部变量x或参数x,Python将直接使用它并停止后续搜索。
其次查找全局名字空间,即当前模块作用域。若模块中定义了名为x的变量、函数或类,Python将使用它并停止搜索。
最后查找内置名字空间,这对所有模块通用。若前两步未找到,Python会假设x为内置函数或变量。
若Python在上述所有名字空间中均未找到x,将停止查找并抛出NameError异常,提示信息为There is no variable named 'x'。
名字空间在程序运行期间可直接访问。局部名字空间可通过内置函数locals()获取,而全局(模块级)名字空间则通过内置函数globals()获取。
locals()的作用对象是局部(函数)名字空间,而globals()的作用对象则是全局(模块)名字空间。
相比之下,globals()的功能更为强大,因为模块名字空间不仅包含模块级变量和常量,还囊括了模块内定义的所有函数和类,以及导入到该模块中的任何内容。
回顾一下from module import与import module两种导入方式的区别:
使用import module时,模块本身被导入,但它保持独立的名字空间。因此,访问其函数或属性时必须使用模块名作为前缀,即module.function。
而使用from module import时,实际上是将指定模块中的函数和属性直接导入到当前名字空间中。因此,可以直接访问这些元素,无需再引用来源模块名。
通过调用globals()函数,可以清晰地观察到上述导入机制在名字空间中的具体体现。
5. locals()实例:
def foo(arg, a):
x = 100
y = 'hello python!'
for i in range(10):
j = 1
k = i
print locals()
foo(1,2)
运行结果如下:
{'a': 2, 'i': 9, 'k': 9, 'j': 1, 'arg': 1, 'y': 'hello python!', 'x': 100}
6. locals()返回的是只读视图,无法直接修改;而globals()返回的内容允许修改,原因在于:
locals()实际上并未返回局部名字空间本身,而是返回了一个副本。因此,对返回结果进行修改仅影响副本,不会改变实际局部名字空间中的变量值。
globals()返回的是实际的全局名字空间,而非副本:这与locals()的行为截然相反。
因此,对globals()返回的字典进行的任何修改,都会直接反映并影响全局变量的取值。
#!/usr/bin/env python #coding:utf-8 '''''This is my first python program!''' z = 7 #定义全局变量 def foo(arg): x = 1 print locals() print 'x=',x locals()['x'] = 2 #修改的是局部名字空间的拷贝,而实际的局部名字空间中的变量值并无影响。 print locals() print "x=",x foo(3) print globals() print 'z=',z globals()["z"] = 8 #globals()返回的是实际的全局名字空间,修改变量z的值 print globals() print "z=",z
运行结果如下:
{'x': 1, 'arg': 3}
x= 1
{'x': 1, 'arg': 3}
x= 1
{'foo': <function foo at 0x02A17CF0>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'E:\\workspace\\python day03\\main\\test.py', '__package__': None, '__name__': '__main__', 'z': 7, '__doc__': 'This is my first python program!'}
z= 7
{'foo': <function foo at 0x02A17CF0>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'E:\\workspace\\python day03\\main\\test.py', '__package__': None, '__name__': '__main__', 'z': 8, '__doc__': 'This is my first python program!'}
z= 8
更多关于Python相关内容感兴趣的读者可查看本站专题:《Python函数使用技巧总结》、《Python数据结构与算法教程》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》
希望本文所述对大家Python程序设计有所帮助。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













