LEGB:L>E>G>B
L: local函数内部作用域
E:enclosing函数内部与内嵌函数之间
G:global全局作用域
B:build-in 内置作用域(python解释器默认导入的一些变量,比如list,tuple等)
当查找一个变量时候,首先函数内部,然后是enclosing,接着是global,最后是build-in中。
passline=60 def func(val): #当定义一个函数的时候会引入本地作用域,函数调用的时候val就是本地变量 passline=90 #优先在本地变量查找 if val>=passline: #本地没有定义passline,因此向全局变量查找 print('pass') else: print('faild') def in_func(): #(val,)应用变量后相当于添加属性中,属性和值是一个元组,是不变得。 print(val) #这里的val变量在函数in_func中未定义即本地变量没有,然后向上层encloding寻找,此时函数func内部有val in_func() def Max(val1,val2): return max(val1,val2)#这里的max函数内部和全局都没有定义,当调用的时候逐层向上查找,最后在build-in中查找到 print(Max(80,100)) func(89)
闭包概念:
Closure:内部函数中对enclosing作用域的变量进行引用
函数实质与属性:
1,函数是一个对象(在内存中有存储的空间)
2,函数执行完后内部变量回收(如果中间产生一个变量,并且变量返回,则变量不会被回收)
3,函数属性
4,函数返回值
如果引用了外部enclosing变量,会将变量添加到函数属性中,当再次查找的时候,并不是去函数中查找,而是函数属性中查找
def set_passline(passline): print('%x' % id(passline)) def cmp(val): if val>=passline: print('Pass') else: print('faild') return cmp f_100=set_passline(60) f_150=set_passline(90) print(f_100) print(f_150) print(f_100.__closure__) #这里看出引用的变量作为函数的属性,调用函数的时候,直接使用 print(f_150.__closure__) f_100(89) f_150(89)
结果:5bc40930
闭包作用:封装,代码复用
def my_sum(*arg): print(arg) return sum(arg)
def my_average(*arg): return sum(arg)/len(arg)
def dec(func): def in_dec(*arg):#闭包函数in_dec,函数func将放到in_dec的属性中,参数处理都是交给in_dec来处理,最后计算使用my_sum() print('in dec arg=',arg) if len(arg)==0: return 0 for val in arg: if not isinstance(val,int): return 0 return func(*arg) #这里的fuc是最初传进去的函数 return in_dec #调用dec函数,返回in_dec函数,in_dec函数调用my_sum函数 #紧接着指示函数的赋值,函数的引用发生变化my_sum=in_dec(*arg) my_sum=dec(my_sum) #执行步骤是上面两步 my_average=dec(my_average) print(my_sum(1,2,3,4,5)) print(my_sum(1,2,3,4,5,'3')) print(my_average(1,2,3,4,5)) print(my_average())
1,装饰器用来装饰函数
2,返回一个函数对象
3,被装饰函数标识符指向返回的函数对象
4,语法糖 @deco
上面和闭包一样,装饰器就是对闭包的使用
def dec(func): print('call dec') def in_dec(*arg): print('in dec arg=',arg) if len(arg)==0: return 0 for val in arg: if not isinstance(val,int): return 0 return func(*arg) #这里的fuc是最初传进去的函数 return in_dec @dec#my_sum=dec(my_sum) def my_sum(*arg):#my_sum=in_dec print(arg) return sum(arg) print(my_sum(1,2,3,4,5)) def my_average(*arg): return sum(arg)/len(arg)装饰器详解:
def deco(func): def in_deco(x,y): print('in deco') func(x,y) print('call deco') return in_deco #当解释器执行到@deco时,会调用deco函数,并将bar作为参数传入,然后函数deco返回in_deco # bar=in_deco bar指向in_deco #当调用bar()时候,实际调用in_deco(),在in_deco调用过程中,我们重新调用了原来的bar()函数 @deco def bar(x,y): print('in bar',x+y) print(type(bar)) bar(1,3)