函数LEGB:
L:local函数内部作用域
E:enclosing函数内部与内嵌函数之间,闭包
G:global全局作用域
B:build-in内置作用域
代表了函数调用优先级,L>E>G>B
闭包定义:
对于enclosing作用域内的变量进行引用
闭包的作用:
1、封装
2、代码的封装
示例:
#coding:utf-8
def my_sum(*arg):
if len(arg) == 0:
return 0
for val in arg:
if not isinstance(val, int):
return 0
return sum(arg)
def my_average(*arg):
if len(arg) == 0:
return 0
for val in arg:
if not isinstance(val, int):
return 0
return sum(arg)/len(arg)
将上述两段代码使用闭包方式简洁处理
#coding:utf-8
def my_sum(*arg):
return sum(arg)
def my_average(*arg):
return sum(arg)/len(arg)
def dec(func):
def in_dec(*arg):
if len(arg) == 0:
return 0
for val in arg:
if not isinstance(val, int):
return 0
return func(*arg)
return in_dec
#dec return in_dec -> my_sum
#my_sum = in_dec(my_sum(*arg))
my_sum = dec(my_sum)
my_average = dec(my_average)
装饰器(sh对于闭包的使用):
1、用来装饰函数
2、返回一个函数对象
3、被装饰函数标识符指向返回的函数对象
4、@语法糖
简单示例:
def deco(func):
def in_deco():
print('in deco')
func()
print('call deco')
return in_deco
@deco
def bar():
print('in bar')
bar()
如果在deco函数中没有返回函数,那么最后的调用bar函数将会是一个return Null,可以自己测试得到结果。
def deco(func):
def in_deco(x, y):
print('in deco')
func(x, y)
print('call deco')
return in_deco
@deco
def bar(x, y):
print('in bar', x+y)
bar(1, 2)
在装饰器中加入参数,其实相当于在两个函数中加入参数,首先我们应该清除程序运行的顺序:
deco ->in_deco ->bar因为是这样的顺序,而func()在这里实际上就是bar()。
也可以理解为:
deco(bar) -> in_deco
bar = in_deco
bar() -> in_deco() -> bar()