Python 闭包

参考:

Python-闭包详解
Python的可变类型与不可变类型
官方Resolution of names
官方教程 - 函数的定义

前言:

lua中也有闭包,但一知半解,因为遇到了python的装饰器,需要闭包的基础,再理解一遍

什么是闭包:

有一个很基础的结构
定义一个函数A,在函数A中在定义一个函数B,A返回函数B名
在这里插入图片描述
你可以看出调函数A()其实就是在调用内部函数B
如果把40行的()去掉结果是怎样
在这里插入图片描述
这时候要借助print,打印发现其实返回的是B函数的地址,A()()相当于是B()
如果这里认为闭包就是返回内部函数,那就太小看闭包了,这个只是闭包的其中一个特点
现在加上 函数普遍要用的参数 和 函数普遍要用的局部变量
在这里插入图片描述
会发现函数B中可以调用A中的参数,na 和 pa
也就是函数B绑定了两个变量na,pa
这就是闭包的另一个特性:绑定外部的变量到自己作用域(但不作为自己作用域的局部变量,所以有个拗口的名字,叫做非局部变量)

总结:

闭包:1.调用内部函数 同时 2.绑定外部变量作为自己环境

真的就这么简单吗?

1.写一个算 本金+利息 的闭包,利息为0.2

在这里插入图片描述
这样写是没啥问题,但是有时候你会这么写
在这里插入图片描述
还没运行前就发现n报红了,强行运行后发现在这里插入图片描述
直接翻译:错误的意思是赋值前引用的局部变量’n’
出现错误官方解释,也就是局部变量在引用前没有绑定个值
n为啥会变成局部变量?局部变量是哪里产生的?
函数执行的时候会引入函数局部变量的新符号表,更详细的说,函数中的所有变量赋值都将值存储在本地符号表中,函数中变量引用的时候会按照顺序从不同的符号表中查找这个变量
1.本地符号表
2.封闭函数(闭包)的本地符号表
3.全局符号表
4.内置名称表

现在引出一个新的问题,符号表是什么?看一下Python sysmtable 使用
在这里插入图片描述
回到错误的地方n += n * rate
在调用这个函数的时候,创建新的符号表,有赋值则把n变量放到新的符号表中,在n * rate时候引用是发现本地符号表中的n并没有赋值,则报错
要改变非局部变量,有两种方法:
1.用可变类型变量为外部参数2.用python提供了一个关键字nonlocal
在这里插入图片描述
在这里插入图片描述
内部函数调用外部变量时
如果外部变量是不可变参数,则内部函数中不能改变外部变量
如果外部变量时可变参数,则内部函数中可以改变外部变量
在内部函数中对外部变量加上关键字 nonlocal ,在内部函数中可以改变外部变量

2.容易犯错的地方

在这里插入图片描述
这里5次print 会输出几?
这里要记住,调用顺序,闭包的内部函数,只有在你调用的时候才会运行,在运行add函数的时候都是在给内部函数制造环境,再保存个test()地址,方便之后调用找到地方,不会进入14行给i赋值,只有运行到19行中才会进入15行test()函数中,所以里面的i是4
把代码打入到pycharm中,Debug模式下,看的很清楚
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值