在Python中,我们可能在不同区域定义了相同名称(如函数名称、变量名称等)的对象,那么,在Python中按照什么规则来访问这些变量呢?本文将对这一问题进行详细的探讨。
在Python中,名称空间可以分为4种类型:
(1)局部名称空间(Local Namespace): 在Python中,位于函数内部、for循环、try-except块是常见的局部名称空间的例子。当函数或对应的代码块执行完毕时,局部名称空间中的对象将被删除。
(2)包裹的名称空间(Enclosed Namespace): 当一个函数定义在另外一个函数内部时,前者就定义了一个包裹的名称空间,其生命周期与局部名称空间相同。
(3)全局名称空间(Global Namespace): 该类型属于Python程序级或模块级。模块级的全局名称空间当其被调用时被创建。通常,模块级的名称空间一直保持到解释器退出。
(4)内建的名称空间(Built-in Namespace): 内建名称空间是在Python解释器启动时创建,且不会被删除。
Python变量按照以下规则搜索各个名称空间。
局部(Local) -> 包裹(Enclosed) -> 全局(Global) -> 内建(Built-in)
这通常被称为变量作用域的LEGB规则。
即Python在使用一个变量时,如输出,先从局部名称空间搜索该变量,如局部没有则进一步搜索包裹名称空间,如变量不存在则进一步搜索全局名称空间,直至内建的名称空间。如以上区域都无法获取到访问的变量,则会给出名称未定义的错误。其过程可以使用下图来表示:
下面程序特意定义了几个层次的变量,来观察变量的使用情况。
a = 1
b = 2
c = 3
def fun_outer():
a = 10
b = 20
def fun_inner():
a = 100
b = 200
c = 300
print(f'inner:a={a},b={b},c={c}')
fun_inner()
print(f'outer:a={a},b={b},c={c}')
fun_outer()
print(f'global:a={a},b={b},c={c}')
输出结果如下:
inner:a=100,b=200,c=300
输出情况,读者可以根据程序的提示自行分析。
outer:a=10,b=20,c=3
global:a=1,b=2,c=3
由模块导入的变量需要通过模块名称来引用。
import math
import numpy
pi = 3.14
print(f'pi = {pi}')
print(f'pi = {math.pi}')
print(f'pi = {numpy.pi}')
输出结果如下:
pi = 3.14
pi = 3.141592653589793
pi = 3.141592653589793
理解Python名称空间及作用域非常有必要,以免在实际使用中产生意想不到的问题。最好的做法是尽量使用不同的名称来定义自己需要的对象,以避免混淆,造成程序运行结果达不到预期结果。
本文(完)
新闻热点
疑难解答