所以函数f3)打印的变量x的值为1。当函数f2)执行时,首先在其局部作用域中寻找变量x的定义,没找到,所以继续向外部函数f1)中寻找,这次找到了变量x的定义,即

x = 1

所以函数f2)打印的变量x的值为1。当函数f1)执行时,首先在其局部作用域中寻找变量x的定义,在其局部作用域中找到了变量x的定义,其值为1,所以直接打印变量x的值。同理,当函数f)执行时,首先在其局部作用域中寻找变量x的定义,在其局部作用域中找到了变量x的定义,其值为0,所以直接打印变量x的值。

需要注意的是,如果内部函数将变量声明为全局变量,那么Python就会跳过局部作用域和外部作用域,而直接从全局作用域开始寻找该变量的定义。现在举例说明:

x = 8      #定义一个全局变量
def f():
x = 0      #定义一个局部变量
print '在函数f)中,x=',x
def f1():
global x      #将x声明为全局变量
x = 1      #这个赋值语句并没有定义局部变量,而是修改了全局变量的值
print '在函数f1)中,x=',x
f1()
print '现在函数f)中,x=',x

上面的代码以交互式执行,结果如下所示:


 图9  在内部函数中使用全局变量的情形

从图10可以看出,当函数f1)执行后,其外部函数f)的局部变量并没有发生变化,但是全局变量x的值却变了。这是因为,当在内部函数f1)中将变量x声明为全局变量后,赋值语句

x = 1

的作用并不是在当前函数中定义一个局部变量,因为这时函数f1)会直接到全局作用域中查找变量,所以赋值语句实际的作用是修改了全局变量x的值。

六、函数嵌套时的执行顺序

当初学者遇到多层嵌套的函数时,对于各个函数的执行顺序经常感到非常头疼,不过不要紧,我们这里向大家介绍一种非常简单的办法,让您轻松读懂代码的执行顺序。

我们曾经说过,在使用def语句定义函数时,Python遇到该语句并不会立即执行其语句体中的代码,只有遇到该函数的调用时,对应def语句的语句体才会被执行。所以,当我们分析嵌套函数的执行顺序时,遇到def语句可以先行跳过包括其语句体),然后遇到函数调用时,在返回头来查看对应def语句的语句体。我们以下列代码进行说明:

def f():
x = 0
print '当前正在执行函数f),其变量x的值为:',x
def f1():
x = 1
print '当前正在执行函数f1)中,其变量x的值为:',x
def f2():
x = 2
print '当前正在执行函数f2)中,其变量x的值为:',x
def f3():
x = 3
print '当前正在执行函数f3)中,其变量x的值为:',x
f3()
f2()
f1()

上述代码在交互式环境下的执行情况如下所示:


图10  多层嵌套函数执行顺序示例1

现在分析一下上述代码的执行过程。首先,当我们在命令提示符下调用函数f)时,解释器会寻找到该函数的定义。在函数f)的定义的第一行下面,虽然这里的代码很多,但是我们只关心冒号下面的第一次缩进所涉及的那些语句,在这里有四个语句,一个赋值语句,一个打印语句,一个def语句,一个函数调用语句。注意,这里的def语句及其语句体可以先跳过去。所以,除了def语句外,这四条语句的执行顺序基本上是顺序执行的,即先给变量x赋值,令其为整数0,再输出变量x的值,这时系统将输出:

当前正在执行函数f),其变量x的值为: 0

然后调用f1),最后找到定义f1)的def语句,并执行其语句体。我们看到,在定义f1)的def语句下面的第一次缩进对应有四条语句,分别也是一个赋值语句,一个打印语句,一个def语句,一个函数调用语句。执行时,先赋值,即将变量x赋值为1,再打印,系统输出以下内容:

当前正在执行函数f1)中,其变量x的值为: 1

遇到def语句先跳过,继而执行函数调用,这次调用的是函数f2)。我们找到定义该函数的def语句,并执行该语句第一行下面第一次缩进对应的四条语句。首先将变量x赋值为2,再打印,系统输出以下内容:

当前正在执行函数f2)中,其变量x的值为: 2

接着,先跳过def语句,直接执行函数调用,这次调用的是函数f3)。我们找到定义该函数的def语句,并执行其第一行下面第一次缩进对应的两条语句。首先将变量x赋值为3,再打印变量的值,如下所示:

当前正在执行函数f3)中,其变量x的值为: 3

好了,至此这个多层嵌套的函数的执行过程至此分析完毕。作为一个练习,读者可以按照上面介绍的方法分析一下下列代码,然后在交互环境中执行一下,看看分析的对不对:

def f():
x = 0
def f1():
x = 1
def f2():
x = 2
def f3():
x = 3
print '目前在函数f3)中,变量x的值为:',x
f3()
print '目前在函数f2)中,变量x的值为:',x
f2()
print '目前在函数f1)中,变量x的值为:',x
f1()
print '目前在函数f)中,变量x的值为:',x


评论关闭