python函数的特性_Python的闭包特性

Python有一个有点让人费解的闭包特性,这个特性的基本特征是在函数中定义嵌套函数,并且外层函数将内层嵌套的函数作为返回值!其实我理解闭包特性实现了好几个特别的功能,给Python函数提供了静态变量,实现了相同函数的不同执行副本,还有python装饰器本质上就是一个闭包。本文记录我对Python闭包特性的理解和应用考虑。

静态变量

Python函数有静态变量吗?没有。要么global,要么就是自己的局部变量,函数退出了这些局部变量就失效。静态变量这个概念来自C语言,用static申明的变量,其地址在程序的data段(永久存在),而且只能够被某个函数访问。在Python中,我们可以用闭包这个特性,实现Python版的静态变量。

def staticVar():

times = 0

def showTimes():

nonlocal times

times += 1

print(times)

return showTimes

f = staticVar()

f()

f()

f()

f()

f()

staticVar函数内定义了一个showTimes函数,这个函数使用nonlocal关键词申明了times不是local的变量,而是staticVar函数内的times。直接运行staticVar函数是没有什么意义的,用f来承接内嵌的showTimes函数,实际上我们要运行的,是内嵌的那个函数,现在名字成了f,然后调用f函数5次,下面是打印出来的效果:

$ python3 cc.py

1

2

3

4

5

times这个变量,就成了f函数(showTimes函数)的静态变量。

执行副本

副本这个词来自网游,用在这里,是我主观臆断的。

很多函数在执行的时候,都会依赖一些变量或标志位,函数根据这些变量或标志位来调整自己的行为,在各种if语句中走不同的分支,输出不同的结果。我们常规的做法,就是给函数不同的入参,或者在函数执行前,先调整全局变量或标志位的值。Python的闭包,给了另外一种选择。

def createRunEnv(location=None):

def run():

print('I am running at',location)

# do something specificly

return run

f_Aisa = createRunEnv('Aisa')

f_Africa = createRunEnv('Africa')

f_Europe = createRunEnv('Europe')

f_Aisa()

f_Africa()

f_Europe()

createRunEnv函数返回的函数,带上了location属性。f_Aisa,f_Africa和f_Europe就是内部函数run的3个不同的副本,调用这3个函数,其内部的location参数是不同的。以上代码执行如下:

$ python3 fb.py

I am running at Aisa

I am running at Africa

I am running at Europe

这种函数副本的好处是,我理解也是封装。将一些参数封装起来,在创建副本的时候确定值,在执行时,只有副本可以访问,以确定自己的运行环境。对同一个函数的不同的执行环境进行打包封装!

以上介绍Python闭包带来的静态变量和函数副本的功能,其实从逻辑上看,没有闭包也可以实现(C语言什么不能实现)。只是有了闭包后,Python代码的书写更加灵活,使用这些特性,代码看起来更加清爽迷人,封装的更加优雅炫酷,当然前提是要能理解这些语法特性。如果传入闭包的参数中有函数,这就是装饰器的本质。

-- EOF --

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值