零基础入门学习Python(11):内嵌函数、闭包和变量作用域
内嵌函数(也称为内部函数)
>>> def fun1():
print('fun1()正在被调用...')
def fun2(): #在func1()中定义一个函数func2()
print('fun2()正在被调用...')
fun2() #此处是fun1()调用fun2()!!!
>>> fun1()
fun1()正在被调用...
fun2()正在被调用...
闭包
>>> def FunX(x):
def FunY(y):
return x * y
return FunY #返回值是一个内部定义的函数。返回的函数带参数时,则直接写出函数名
>>> i = FunX(8)
>>> i
<function FunY at 0x010601E0>
>>> type(i)
<class 'function'>
>>> i(5)
40
>>> FunX(8)(5) #闭包可以实现输入不同参数
40
不能在外部函数调用内部函数和闭包。
下面介绍下变量作用域:
>>> num = 7 #全局变量
>>> def test1():
num = 2 #函数中,局部变量,与全局变量同名
print(num)
>>> test1()
2
>>> num #全局变量值没有改变。
7
Python中,可以读取全局变量的值,但是当局部变量与全局变量同名且需要改变时,Python为了保护全局变量,会自动生成一个局部变量。如果想要在函数中改变全局变量的值,需要加上global关键字
>>> def test2():
global num #global关键字说明函数中使用的是全局变量
num = 2
print(num)
>>> num #没有调用test2()之前,全局变量num=7
7
>>> test2()
2
>>> num #调用test2()之后,全局变量改变了
2
当定义内部函数或者闭包时,有时需要改变函数中的变量,此时,该变量相对于内部函数或者闭包是全局的,如果想要直接改变该变量的值就会出错,如下:
>>> def test3():
x = 5 #相对test4()就是全局变量
def test4():
x **= 2 #上面的x =5被屏蔽掉了,Python重新生成了一个x,但没有初始值
return x
return test4()
>>> test3() #直接改变x的值会出错
UnboundLocalError: local variable 'x' referenced before assignment
要想解决这种问题,有两种方法
第一种方法是:把变量值存储在列表中
>>> def test3():
x = [5] #因为列表不是存放在栈里面,所以变量不会被屏蔽掉
def test4():
x[0] **= 2
return x[0]
return test4()
>>> test3()
25
第二种方法是:使用nonlocal关键字
>>> def test3():
x = 5
def test4():
nonlocal x #把x强制说成不是局部变量
x **= 2
return x
return test4()
>>> test3()
25