我的理解是,在一般而非使用exec函数的情况下,举个例子:
x = 1
def A():
x = 2
def B():
x = 3
def C():
print(x)
C()
B()
A()
这里,在函数C中,由于没有使用x = 4之类的语句来从函数C的作用域内声明局部变量,因而print(x)在C的作用域内找不到变量x,那么就只能向外一层去找,假设我注释掉x=3,即:
x = 1
def A():
x = 2
def B():
#x = 3
def C():
print(x)
C()
B()
A()
那么,它会继续向外一层寻找名为x的变量,也就是说,在一般情况下,如果在当前作用域内找不到某名称的局部变量的话,就会不断地向外一层寻找。但是,exec函数似乎有些不同。
它有两个参数,一个用来指定全局变量,一个用来指定局部变量,它们的运行机制似乎是这样的:
局部变量参数是用来设定""" """向内仅一层的变量,在本例中就是与a =3处于同一层的其它位置,因此,在a = 3前一行插入使用print(a)打印出来的会是向exec函数传入的局部变量(即打印出 2);在a = 3后一行插入使用print(a)打印出来的会是3,因为此时,a = 3是在这一层命名空间中对局部变量a的最新赋值。
全局变量参数是用来设定""" """向内第二层(在本例中是函数f的作用域)的“向外一层”,即,如果按照通常的规定话,函数f内如果没有需要的变量会向外一层寻找,即本该在与a = 3相同的一层内寻找,但exec函数特别规定,""" """向内第二层内如果在其作用域内找不到变量的话就直接从全局变量参数所规定的内容中寻找,并且,如果还是找不到的话就报错,这相当于人为指定全局变量参数所规定的内容就是“最外层”。
举个例子:
template = """
a = 3
def f():
def g():
def h():
print(a)
h()
g()
f()
"""
globals_ns = {'a': 1}
locals_ns = {'a': 2}
exec(template, globals_ns, locals_ns)
如果这样写的话,那么,在嵌套的h()函数的作用域内会首先查找名为a的变量,但找不到,那么便向外一层的g()中去找(如果找得到,那么自然取值是g()内的a的值),此时,还是找不到,便再向外层的f()中找,但此时还是找不到,最终是从exec函数传入的全局变量参数的内容中找,即打印结果为 1
回到最开始的例子来:由于从函数f()中找不到名为a的变量,但向外一层却又直接到了局部变量参数规定的范围内,那么别无他法,只能尝试从全局变量参数中寻找名为a的变量,这里,在全局变量参数globals_ns中正好找到了名为a且取值为1的变量,因而print(a)时找到的变量就是它
x = 1
def A():
x = 2
def B():
x = 3
def C():
print(x)
C()
B()
A()
这里,在函数C中,由于没有使用x = 4之类的语句来从函数C的作用域内声明局部变量,因而print(x)在C的作用域内找不到变量x,那么就只能向外一层去找,假设我注释掉x=3,即:
x = 1
def A():
x = 2
def B():
#x = 3
def C():
print(x)
C()
B()
A()
那么,它会继续向外一层寻找名为x的变量,也就是说,在一般情况下,如果在当前作用域内找不到某名称的局部变量的话,就会不断地向外一层寻找。但是,exec函数似乎有些不同。
它有两个参数,一个用来指定全局变量,一个用来指定局部变量,它们的运行机制似乎是这样的:
局部变量参数是用来设定""" """向内仅一层的变量,在本例中就是与a =3处于同一层的其它位置,因此,在a = 3前一行插入使用print(a)打印出来的会是向exec函数传入的局部变量(即打印出 2);在a = 3后一行插入使用print(a)打印出来的会是3,因为此时,a = 3是在这一层命名空间中对局部变量a的最新赋值。
全局变量参数是用来设定""" """向内第二层(在本例中是函数f的作用域)的“向外一层”,即,如果按照通常的规定话,函数f内如果没有需要的变量会向外一层寻找,即本该在与a = 3相同的一层内寻找,但exec函数特别规定,""" """向内第二层内如果在其作用域内找不到变量的话就直接从全局变量参数所规定的内容中寻找,并且,如果还是找不到的话就报错,这相当于人为指定全局变量参数所规定的内容就是“最外层”。
举个例子:
template = """
a = 3
def f():
def g():
def h():
print(a)
h()
g()
f()
"""
globals_ns = {'a': 1}
locals_ns = {'a': 2}
exec(template, globals_ns, locals_ns)
如果这样写的话,那么,在嵌套的h()函数的作用域内会首先查找名为a的变量,但找不到,那么便向外一层的g()中去找(如果找得到,那么自然取值是g()内的a的值),此时,还是找不到,便再向外层的f()中找,但此时还是找不到,最终是从exec函数传入的全局变量参数的内容中找,即打印结果为 1
回到最开始的例子来:由于从函数f()中找不到名为a的变量,但向外一层却又直接到了局部变量参数规定的范围内,那么别无他法,只能尝试从全局变量参数中寻找名为a的变量,这里,在全局变量参数globals_ns中正好找到了名为a且取值为1的变量,因而print(a)时找到的变量就是它