Python中locals与globals函数的区别及原理详解
本文深入解析Python中locals()和globals()函数的核心差异。通过理解局部、全局及内置名字空间的查找顺序,明确locals返回的是局部变量的副本(只读修改无效),而globals返回实际的全局名字空间字典(可直接修改全局变量)。结合代码示例,阐明两者在变量访问与修改行为上的不同机制。
Python名字空间基础概念
这两个内置函数的主要作用是提供基于字典形式访问局部变量和全局变量的途径。要准确理解它们,首先需要掌握Python中的名字空间(Namespace)概念。Python利用名字空间来追踪变量的存储位置,本质上它是一个字典结构,其中键(key)为变量名,值(value)为对应的变量值。在Python中,名字空间的访问方式与标准字典类似。
每个函数都拥有独立的局部名字空间,用于记录该函数内部的变量,包括传入的参数以及函数体内定义的局部变量。每个模块则拥有自己的全局名字空间,记录模块层面的变量,涵盖函数定义、类定义、导入的其他模块、模块级变量及常量等。此外,还存在内置名字空间,对所有模块全局可见,其中存放着Python内置的函数和异常类。
变量查找顺序机制
当代码执行需要获取变量x的值时,Python会按照特定的优先级顺序在各个名字空间中搜索该变量,具体查找顺序如下:
1. 局部名字空间:指当前正在执行的函数或类的方法。如果在该函数的局部变量中找到了名为x的变量,Python将直接使用它,并停止后续搜索。
2. 全局名字空间:指当前所在的模块。如果在模块的全局变量中找到了名为x的变量(无论是函数、类还是其他变量),Python将使用它,并停止搜索。
3. 内置名字空间:这是所有模块共享的全局空间。如果在前两层中均未找到x,Python会最后尝试在内置名字空间中查找x,将其视为内置函数或变量。
如果Python在上述所有名字空间中均未找到变量x,它将停止查找并抛出一个NameError异常,同时提示信息为There is no variable named 'x'。
locals与globals的行为差异
以下是关于局部变量函数locals()的示例代码(locals()返回一个包含名字/值对的字典):
def foo(arg, a):
x = 1
y = 'xxxxxx'
for i in range(10):
j = 1
k = i
print(locals())
#调用函数的打印结果
foo(1,2)
[python@master test]$ python3 f.py
{'arg': 1, 'a': 2, 'x': 1, 'y': 'xxxxxx', 'i': 9, 'j': 1, 'k': 9}
需要注意的是,locals()返回的结果是只读的,无法通过直接修改返回值来改变局部变量;而globals()返回的结果是可以修改的。造成这种差异的原因在于:
调用locals()时,Python实际上返回的是当前局部名字空间的一个副本(拷贝)。因此,对locals()返回的字典进行修改,实际上只是修改了这个副本,而不会影响到函数内部实际的局部变量值。
相比之下,globals()返回的是实际的全局名字空间字典本身,而非副本。这与locals()的行为截然相反。
因此,对globals()所返回的字典进行任何修改,都会直接反映并影响到实际的全局变量取值。
#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)
[python@master test]$ python3 h.py
{'arg': 3, 'x': 1}
x= 1
{'arg': 3, 'x': 1}
x= 1
{'__name__': '__main__', '__doc__': 'This is my first python program!', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fb2f23db400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'h.py', '__cached__': None, 'z': 7, 'foo': <function foo at 0x7fb2f245d1e0>}
z= 7
{'__name__': '__main__', '__doc__': 'This is my first python program!', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fb2f23db400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'h.py', '__cached__': None, 'z': 8, 'foo': <function foo at 0x7fb2f245d1e0>}
z= 8
以上内容涵盖了Python中locals与globals函数的核心区别与工作原理,希望能为读者的学习提供有益参考,也欢迎大家继续支持本站获取更多技术分享。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









