先了解python的闭包是什么
简单来说闭包是函数包函数,先举个例子:
#创建闭包------ def apple(): a = 10 def banana(): z = a+10 print("三个数的和为{0}".format(z)) return banana #返回的是banana函数
上面是一个简化的闭包,可以看出闭包有几个特点
1、有内部函数(banana)
2、又返回值,且返回的是内部函数名
3、一般来说内部函数会引用外部变量
这个时候当你调用apple函数时,会return会返回banana这个函数给你,所以直接调用apple(),并不会调用内部的banana
如果你想调用内部的函数,需要用一个东西来接内部函数才能调用,例如:
m = apple() m() #这时的m 变成了banana
那么闭包有什么用呢
闭包可以做一些嵌套,例如
def mycounter(): counter = [0] def innerfunc(): counter[0] = counter[0]+1 print("你访问的次数为{0}".format(counter[0])) return innerfunc
这里做了个计数器,每次访问时都会记录下来
a = mycounter() a() a() a()
你访问的次数为1
你访问的次数为2
你访问的次数为3
Process finished with exit code 0
除此之外闭包对装饰器的理解也很重要
当你创建了一个函数,发现它过于单调,想要丰富它,可以使用装饰器
这可以实现两个函数的合并
需要装饰器时闭包的外部函数会是这样:
def car(func): benz = 100 def price(): money = benz * 10000 print("奔驰的价钱是{0}".format(money)) return price
这时你拥有的简单函数:
def show(): print("谢谢惠顾")
可以在上面加@函数名(car)---------使用装饰器
分析一下底层逻辑:
@car def show(): print("谢谢惠顾")
这里的@car会创建car函数,然后将show函数放进func,这时func=show
然后创建price函数,返回price,这个时候我们并没有拿东西接price,price被func接住了,price=func
此时show就相当于price了,所以当你print(show)的时候会发现它其实是price
这时你会发现那原来的show函数用不了了
所以你需要在price函数里调用func(),因为此时的func是show
def car(func): benz = 100 print("开始估算") def price(): money = benz * 10000 print("奔驰的价钱是{0}".format(money)) func() return price
那如果你的简单函数里需要输入参数
而price不需要参数,这会导致错误,此时你可以在price中也传入参数,并将参数传入func()中
def car(func): benz = 100 print("开始估算") def price(n): money = benz * 10000 print("奔驰的价钱是{0}".format(money)) func(n) return price @car def show(n): print("谢谢惠顾",n) show("Mr.zhang")
当然如果你想要输入万能的东西,可以在闭包的内部函数(price)里加入*args,**kwargs
def price(*args,**kwargs): money = benz * 10000 print("奔驰的价钱是{0}".format(money)) func(*args,**kwargs)
这样你无论传的是列表,字典,声明参数等等都是可以的