一.定义,什么样的叫闭包?
在Python语言中,一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包。你在调用函数A的时候传递的参数就是自由变量。简单的说,内部函数可以使用外部函数变量的行为,就叫闭包。
二. 为什么使用闭包?
因为在工作中,闭包可以缩减我们的代码量,可以偷懒,在一些场合还可以降低资源的消耗。闭包的几个特点:
1.与父函数中的变量建立关联,减少文件中全局变量的使用。有利于后面发展的并行运算。
2.即便生成闭包的环境-父函数已经释放,闭包还是会存在即内部变量的值还是存在于内存中。
三.实例说明
1.平常中,有些类的功能可以通过闭包的方式来实现,以达到缩减代码量的目的。
## 类
class Food(object):
def __init__(self,food):
self.food=food
#self.name=name
def eat_food(self,name):
print "{}偷吃了{}".format(name,self.food)
apple=Food('apple')
apple.eat_food('小明')
## 闭包方式
def Fruit(fruit):
def eat(name):
print '{}偷吃了{}'.format(name,fruit)
return eat
man=Fruit('milk')
man('小强')
2.装饰器在很多时候就是闭包的一种应用,不过装饰器传递的是函数体。比如下面带参的装饰器Auth():
def Auth(auth_type):
def wrap(func):
def inner(*args,**kwargs):
if auth_type=='local':
name=raw_input('输入用户名:')
passwd=raw_input('输入密码:')
if auth_type=='local':
if name=='admin' and passwd=='admin':
print('登陆成功!')
func(*args,**kwargs)
else:
print('登录失败')
if auth_type=='ldap':
print '喔,你改用ldap方式认证啦'
func(*args,**kwargs)
return inner
return wrap
@Auth('local')
def Tv(price):
print('电视售价:{}'.format(price))
@Auth('ldap')
def Index():
print('欢迎来到XXX')
Tv(3500)
Index()
不带参的装饰器f():
def wrap(fun):
def inner(*args,**kwargs):
print 'call function {}():'.format(fun.__name__)
return fun(*args,**kwargs)
return inner
@wrap
def tv():
print 'Welcome'
tv()
##输出
call function tv():
Welcome
可以看到带有参数的装饰器比没带参数的装饰器多了一层包裹。
3. 在闭包中使用循环变量有个陷阱
可以看见,结果并未如一些人预料到的1,4,9 。 原因就是闭包内部的inner()是在for循环结束的时候才开始执行的。由此,为了避免一些预料外的错误,应尽量不在闭包中使用循环变量。
当然在特殊情况下的补救措施也是有的-对内部函数再包一层,借用函数的参数来保存每次循环后的变量值:
参考资料:
2.http://funhacks.net/2016/11/17/closure/
3.https://segmentfault.com/a/1190000004461404