首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

python闭包的定义及注意事项

闭包函数的定义

闭包是函数+环境变量组成,其中环境变量是指闭包中的变量,闭包函数的子函数中的变量不能与闭包中的函数名称相同。例如下方案例中,变量a时闭包函数的环境变量,这个环境变量不能在子函数curve中更新,否则整个闭包函数就会变成普通的函数,闭包相关的操作也将失效:

# 定义闭包函数

def curve_pre():

a = 25

# 定义闭包的回调函数

def curve(x):

return a * x * x

return curve

f = curve_pre()

res = f(11)

print(res)

闭包中的环境变量全部存储在一个内置的变量【__closure__】中,如果我们想要查看某个闭包的所有变量可以使用如下方式:

def curve_pre():

a = 25

def curve(x):

return a * x * x

return curve

f = curve_pre()

print( f.__closure__ ) #打印结果:

注意了,如果我们在子函数curve中更新闭包函数的环境变量,那么此时,__closure__ 返回空,因为闭包函数认为变量a不是环境变量,会把变量a变成局部变量,这也破坏了闭包的定义。

实际应用

假设我们需要封装函数来计算一个人的步行的距离,一般情况下都会使用如下方式:

origin = 0

def go(step):

global origin

origin = origin + step

return origin

# 每走n步记录一次

print(go(2)) # 打印结果:

print(go(2)) # 打印结果:

print(go(2)) # 打印结果:

注意:go函数中的 global 的作用是申明某个变量为全局变量

虽然我们可以通过全局变量方式去保存历史数据,但是这种方式可能会破坏代码的架构性,很容易搞混变量,毕竟全局变量很容被其他地方更新。但是闭包就可以很好的解决,具体代码如下:

def factory():

origin = 0

def go(step):

origin = origin + step

return origin

return go

f = factory()

print(f(2))

print(f(2))

print(f(2))

这样一来就不会涉及到全局变量污染的问题了。

这里的初始值是固定的,为了代码的可维护性,有的时候需要从外传值来定义初始值,闭包也是支持的,在子函数中使用时只需要通过关键字 nonlocal 申明即可,具体代码如下:

def factory(origin):

def go(step):

nonlocal origin

origin = origin + step

return origin

return go

origin = 10

f = factory(origin)

print(f(2))

print(f(2))

print(f(2))

虽然闭包可以解决全局变量污染的问题,但是闭包的方式非常容易导致内存泄漏,因为闭包函数的环境变量单独存储在__closure__ 中,这里面的变量无法及时的得到内存的释放。在日常工作做我们需要自己去衡量是否使用闭包,在什么场景下使用等问题

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OGhmW8GGa2kKEUwZ8sOAbi9A0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券