📅  最后修改于: 2020-05-11 14:10:06             🧑  作者: Mango
命名空间:命名空间是一个将名称映射到对象的容器,用于在不同命名空间中存在相同名称的情况下避免混淆。 它们是由模块,函数,类等创建的。
作用域:作用域定义了层次结构顺序,在该层次结构中,必须搜索名称空间才能获得名称到对象 (变量)的映射。 它是一个存在变量并从中引用变量的上下文。 它定义了变量的可访问性和生存期。 让我们举一个简单的例子,如下所示:
pi = 'outer pi variable'
def print_pi():
pi = 'inner pi variable'
print (pi)
print_pi()
print (pi)
输出:
inner pi variable
outer pi variable
上面的程序提供了不同的输出,因为相同的变量名pi驻留在不同的名称空间中,一个位于函数print_pi内 ,另一个位于高层。 当执行print_pi()时,将打印“ inner pi variable “,因为它是函数名称空间内的pi值。 当在外部名称空间中引用pi时,将输出值“ external pi variable “。 从上面的示例中,我们可以猜到肯定有一条规则可以遵循,以便确定必须从哪个名称空间中选择变量。
通过LEGB规则进行范围解析:
在Python中, LEGB规则用于确定搜索名称空间以进行范围解析的顺序。
以下是按层次结构列出的范围(从最高到最低/从最窄到最宽):
Local范围:
局部Local作用域是指在当前函数中定义的变量。函数将首先在其局部作用域中查找变量名。 只有在该处找不到它时,才检查外部作用域。
# 局部Local作用域
pi = 'global pi variable'
def inner():
pi = 'inner pi variable'
print (pi)
inner()
输出:
inner pi variable
在运行上述程序时, 内部函数的执行将打印其本地变量(LEGB规则中的最高优先级)变量pi的值,因为它是在本地范围内定义并可用的。
本地和全局范围:
如果未在局部范围内定义变量,则将在较高范围(在本例中为全局范围)中检查该变量。
# 全局范围
pi = 'global pi variable'
def inner():
pi = 'inner pi variable'
print (pi)
inner()
print (pi)
输出:
inner pi variable
global pi variable
因此,按预期,程序会在执行inner()时在本地范围内打印出该值。 这是因为它是在函数内部定义的,这是查找变量的第一位。 在第9行执行print(pi)时 ,将打印全局范围内的pi值。
局部,封闭和全局范围:
对于封闭的范围,我们需要定义一个封闭内部函数的外部函数,注释掉内部函数的本地pi变量,并使用nonlocal关键字引用pi 。
# 封闭范围
pi = 'global pi variable'
def outer():
pi = 'outer pi variable'
def inner():
# pi = 'inner pi variable'
nonlocal pi
print (pi)
inner()
outer()
print (pi)
输出:
outer pi variable
global pi variable
当执行external()时,将执行inner()并随后执行打印函数,该函数将打印在封闭的pi变量。 第10行中的语句在inner的局部范围内寻找变量,但在那里找不到它。 由于pi是使用nonlocal关键字引用的,因此意味着pi需要从外部函数(即外部范围)进行访问。 总而言之,在局部作用域中找不到pi变量,因此将查找更高的作用域。 在封闭范围和全局范围中都可以找到它。 但是按照LEGB层次结构,即使我们在全局范围中定义了一个变量,也要考虑封闭的范围变量。
本地,封闭,全局和内置范围:
可以通过从数学模块导入pi并注释全局,封闭和局部pi变量来完成最终检查,如下所示:
# 内置范围
from math import pi
# pi = 'global pi variable'
def outer():
# pi = 'outer pi variable'
def inner():
# pi = 'inner pi variable'
print (pi)
inner()
outer()
输出:
3.141592653589793