Python进阶:闭包和装饰器

张开发
2026/6/21 19:40:15 15 分钟阅读
Python进阶:闭包和装饰器
一、闭包1.闭包的前提条件及定义前提条件有嵌套有引用有返回定义有内部函数的嵌套内部函数使用了外部函数的局部变量外部函数对内部函数进行了返回。注意内部函数依赖外部函数的变量以此让内部函数正常运行同时它依赖的外部变量也能得到想要的结果。2.闭包的语法结构defouter(out_a):definner(in_b):print(out_a,in_b)returninner fnouter(闭包)fn(语法结构)调用outer函数返回的是inner函数用一个变量fn接收因此变量fn的类型为一个可以接收参数的函数。程序运行结果3.nonlocal关键字下面通过一段错误代码来介绍nonlocal关键字defouter(num1):definner(num2):num1num2print(num1)returninner fnouter(5)fn(5)程序会直接报错num1是外部函数outer的局部变量不能在内部函数直接进行修改。那如何正确的对外部函数的局部变量num1进行修改呢答案是使用nonlocal关键字。defouter(num1):definner(num2):nonlocalnum1 num1num2print(num1)returninner fnouter(5)fn(5)程序运行结果nonlocal关键字的作用在内部函数中修改外层函数的局部变量声明变量既不是全局变量 也不是自己的局部变量而是外部函数的局部变量。在内部函数中使用nonlocal关键字从而修改外部函数的变量的值二、装饰器1.定义装饰器的本质是函数也是特殊的闭包可以理解为在不修改函数原有代码的前提下为函数添加新的功能。2.装饰器的写法1) 闭包写法把原函数show传给装饰器得到闭包函数用返回的闭包函数覆盖原来的函数名之后调用get_show函数其实是执行内层函数inner。# 定义装饰器使用闭包defouter(func):definner():print(原函数添加功能之前)# 调用原函数get_showfunc()print(原函数添加功能之后)returninner# 定义原函数defget_show():print(我是原函数)fnouter(get_show)fn()2) 语法糖将装饰器名 写在原函数上方再直接调用原函数。# 定义装饰器使用闭包defouter(func):definner():print(原函数添加功能之前)# 调用原函数get_showfunc()print(原函数添加功能之后)returninnerouter# 定义原函数defget_show():print(我是原函数)get_show()两种写法的运行结果相同3) 两种写法的总结闭包写法先调用装饰器的外部函数outer将原函数get_show传入得到返回值fn而返回值本质就是装饰器的内部函数inner最后再调用inner函数。语法糖写法先定义好装饰器函数用装饰器名写在原函数上方最后再调用原函数。三、global和nonlocal关键字对比1.作用范围global用于修改全局变量函数外部定义的变量。nonlocal用于修改外层函数的局部变量嵌套函数中外层函数的局部变量。2.使用场景global在任意函数内部想要修改函数外部的全局变量时使用。nonlocal在嵌套内层函数中想要修改外层函数的局部变量时使用。global的示例代码num100# 全局变量deftest():globalnum# 声明使用全局变量num10# 修改全局变量test()print(num)# 输出 10nonlocal的示例代码defouter():num10# 外部函数局部变量definner():nonlocalnum# 声明使用外部变量num20# 修改外部变量inner()print(num)# 输出 20outer()四、总结闭包满足嵌套引用返回三个条件内层函数可使用并记住外层函数变量修改外层变量需用nonloca关键字l。装饰器本质是特殊闭包在不修改原函数代码的前提下为函数添加新功能支持闭包手动写法和语法糖简化写法。关键字global 改全局变量nonlocal 改外层函数局部变量二者都用于解决函数内变量修改作用域问题。

更多文章