Python中嵌套函数和闭包函数讲解

嵌套函数定义:

嵌套函数类似于嵌套循环,就是函数内又嵌套着函数。先看一种容易理解的情况:

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

如果想修改外部函数中的变量,必须加一个nonlocal的声明,修改如下。这和在函数中修改全局变量,加global 有异曲同工之妙

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毫升

你可能感兴趣的:(python,python,开发语言)