当前位置:
首页 > temp > python入门教程 >
-
python--高级语法 8
5、闭包
5.1闭包的定义:
-
闭包是嵌套在函数中的函数。
-
闭包必须是内层函数对外层函数的变量(非全局变量)的引用。
闭包的现象:
-
被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系。
-
自由变量不会再内存中消失。
-
''' 由于闭包这个概念比较难以理解,尤其是初学者来说,相对难以掌握,所以我们通过示例去理解学习闭包。 给大家提个需求,然后用函数去实现:完成一个计算不断增加的系列值的平均值的需求。 例如:整个历史中的某个商品的平均收盘价。什么叫平局收盘价呢?就是从这个商品一出现开始,每天记录当天价格,然后计算他的平均值:平均值要考虑直至目前为止所有的价格。 比如大众推出了一款新车:小白轿车。 第一天价格为:100000元,平均收盘价:100000元 第二天价格为:110000元,平均收盘价:(100000 + 110000)/2 元 第三天价格为:120000元,平均收盘价:(100000 + 110000 + 120000)/3 元 ........ ''' # 封闭的东西: 保证数据的安全。 # 方案一: # l1=[] #全局变量 # def make_averager(new_value): # l1.append(new_value) # total=sum(l1) # average=total/len(l1) # return average # # print(make_averager(100000)) # print(make_averager(110000)) # print(make_averager(120000)) # 方案二: 数据安全,l1不能是全局变量。 # def make_averager(new_value): # l1 = [] # l1.append(new_value) # total = sum(l1) # averager = total/len(l1) # return averager # print(make_averager(100000)) # print(make_averager(110000)) # 此方案不行 因为每次执行的时候,l1列表都会重新赋值成空列表[] # 方案三: 闭包 def make_averager(): l1 = [] def averager(new_value): l1.append(new_value) total = sum(l1) averager1 = total/len(l1) return averager1 return averager avg=make_averager() #avg这个变量得到是 averager这个函数名 print(avg(100000)) #相当于执行---averager(100000) print(avg(110000)) #思考:avg=make_averager() 这句代码执行完,理论上l1这个列表消失了,可是为什么没有消失? #因为产生了闭包 100000.0 105000.0 Process finished with exit code 0
5.2闭包的作用:
- 保存局部信息不被销毁,保证数据的安全性
5.3如何判断一个嵌套函数是不是闭包
- 1,闭包只能存在嵌套函数中
- 2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。
# 例一:
def wrapper():
a = 1
def inner():
print(a)
return inner
ret = wrapper()
#例一是闭包
# 例二:
a = 2
def wrapper():
def inner():
print(a)
return inner
ret = wrapper()
#例二不是闭包
# 例三:
def wrapper(a,b):
def inner():
print(a)
print(b)
return inner
a = 2
b = 3
ret = wrapper(a,b)
#也是闭包
5.4如何用代码判断闭包?
- 查看这个函数有没有自由变量就行了
# 函数名.__code__.co_freevars 查看函数的自由变量
print(avg.__code__.co_freevars) # ('series',)
# 函数名.__code__.co_varnames 查看函数的局部变量
print(avg.__code__.co_varnames) # ('new_value', 'total')
# 函数名.__closure__ 获取具体的自由变量对象,也就是cell对象。
# (<cell at 0x0000020070CB7618: int object at 0x000000005CA08090>,)
# cell_contents 自由变量具体的值
print(avg.__closure__[0].cell_contents) # []
上面例三最难判断是不是闭包,为了进一步确认,用代码判断闭包
# 例三:
def wrapper(a,b):
def inner():
print(a)
print(b)
return inner
a = 2
b = 3
ret = wrapper(a,b)
#如何用代码判断闭包?
print(ret.__code__.co_freevars)
('a', 'b')
Process finished with exit code 0
5.5闭包的应用:
- 可以保存一些非全局变量但是不易被销毁、改变的数据。
- 装饰器。
5.6闭包面试题怎么问?
- 什么是闭包? 闭包有什么作用。
出处:https://www.cnblogs.com/wushaofan/p/17156647.html
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数