嵌套函数类似于嵌套循环,就是函数内又嵌套着函数。先看一种容易理解的情况:
def func2(): #定义一个函数
print('我是第二个函数')
def func1(): #再定义一个函数
print('我是第一个函数')
func2()
func1()
大家想一下结果:
# 输出结果为
我是第一个函数
我是第二个函数
如果把被调用函数写在函数内部呢,那就是嵌套函数了。如下:
>>>def outer(): #定义外层函数
print('我是外层函数')
def inner(): #定义内层函数
print('我是内层函数')
inner() #执行内层函数
>>>outer()
我是外层函数
我是内层函数
调用外部函数outer()后,先执行print('我是外层函数'),最后执行inner(),而inner函数内是print('我是内层函数'),所以最后输出了两句话。
这种嵌套函数看着没有什么特别之处,搞得还复杂,有什么作用呢?别急,请往下看:
以上外层函数和内层函数都没有变量,和参数,那如果传入参数和变量呢?然后把外层函数返回值指向内层函数名:
def outer(): #定义外层函数
a=1
print('我是外层函数')
def inner(): #定义内层函数
print('我是内层函数')
print('内层函数打印',a)
return inner #返回内层函数名
f=outer() #调用外层函数,并把结果赋值给f
>>>我是外层函数
看到结果只执行了外层函数的print,内层函数没有执行。我们看一下f的含义,此时f其实就代表inner,指向inner的内存空间。如果要执行需要f(),我们看一下结果:
def outer(): #定义外层函数
a=1
print('我是外层函数')
def inner(): #定义内层函数
print('我是内层函数')
print('内层函数打印',a)
return inner #执行内层函数
f=outer() #调用外层函数,并把结果赋值给f
f()
>>>我是外层函数
我是内层函数
内层函数打印 1
看到内层函数和外层函数都执行了,并且外层函数中的变量a被打印出来。这就是闭包函数,外层函数的变量可以被内层函数调用,这样外层函数变量和内层函数一起构成了类似‘’肚子里的一块区域‘’,这块区域被保护起来,变量只供内层函数‘’享用‘’。类似于封装的效果。内层函数不会立马被执行,当再次调用f时,内层函数才会执行。
闭包函数需要有三个条件,缺一不可:
1.必须有一个内嵌函数
2.内部函数引用外部函数变量
3.外部函数必须返回内嵌函数
再把上面的代码变形
def outer(): #定义外层函数
a=1
print('我是外层函数')
def inner(): #定义内层函数
a=10
print('我是内层函数')
print('内层函数打印',a)
return inner #执行内层函数
f=outer() #调用外层函数,并把结果赋值给f
f()
>>>我是外层函数
我是内层函数
内层函数打印 10
在内层函数中又有a=10,此时并不是改变的外层函数中的a,而是在内层函数中定义的新变量,是两个不同的东西。从结果也能看出来。这就是作用域的问题。
内层函数中调用的变量首先会从内层函数中找,找不到就去外层函数中找,再找不到就到函数外代码中找,再找不到就到内置的模块中找,最后还是找不到,就报错。
在内层函数中修改外部函数中的变量a,此时会报错
def outer(): #定义外层函数
a=1
print('我是外层函数')
def inner(): #定义内层函数
a+=10
print('我是内层函数')
print('内层函数打印',a)
return inner #执行内层函数
f=outer() #调用外层函数,并把结果赋值给f
f()
>>>我是外层函数
Traceback (most recent call last):
File "C:\Users\13061\PycharmProjects\huaweidata\迭代器.py", line 14, in
f()
File "C:\Users\13061\PycharmProjects\huaweidata\迭代器.py", line 9, in inner
a+=10
UnboundLocalError: local variable 'a' referenced before assignment
def outer(): #定义外层函数
a=1
print('我是外层函数')
def inner(): #定义内层函数
nonlocal a
a+=10
print('我是内层函数')
print('内层函数打印',a)
return inner #执行内层函数
f=outer() #调用外层函数,并把结果赋值给f
f()
1、上面讲了一点就是把某些变量和函数代码保护到‘’肚子里‘’,这样可以起到保护的作用。
2、可以构造一个新函数,上面例子中外层函数和内层函数都没有传变量,那么如果传入变量呢。
请看:
def outer(a): #定义函数要一杯不同类型的饮料
def inner(b): #定义内层函数,饮料的容量
print(f'要一杯{a}')
print(f'容量是{b}毫升')
return inner #执行内层函数
blacktea=outer('红茶') #调用外层函数,并把结果赋值给f
greentea=outer('绿茶')
blacktea(300)
greentea(500)
>>>要一杯红茶
容量是300毫升
要一杯绿茶
容量是500毫升