Python——闭包和装饰器

来源:互联网 发布:黑龙江药品中标数据网 编辑:程序博客网 时间:2024/05/06 00:55

闭包

1.LEGB原则:

函数对变量进行引用时 按照 LEGB的顺序进行查找:
L:local函数内部作用域
E:enclosing函数内部与内嵌函数之间
G:global全局作用域
B:build-in内置作用域(解释器自动添加)

2.闭包(closure):

内部函数对enclosing作用域的变量进行引用

内部函数用到的enclosing中的变量作为函数的属性保存下来,用_ _ closure_ _可以查看

def outer(val):    print('%x'%id(val))    def inner():        print(val)    return innerf=outer(1)print(f.__closure__)#输出结果val's id:568256f0(<cell at 0x032D2930: int object at 0x568256F0>,)

内部函数的运用:

def set_passline(passline):    def comp(val):#把passline添加到__closure__中        if val>=passline:            print('pass')        else:            print('faile')    return compf_100=set_passline(60)f_150=set_passline(90)f_100(89) #passf_150(89) #faile

闭包作用: 1.封装 2.代码复用

3.闭包到装饰器

闭包类似装饰器的运用:

def my_sum(*args):    return sum(args)def my_average(*args):    return sum(args)/len(args)def dec(func):    def in_dec(*args):        if len(args)==0:            return 0        for val in args:            if not isinstance(val,int):                return 0        return func(*args)    return in_decmy_sum = dec(my_sum)my_average=dec(my_average)print(my_sum(1,2,3,4,5))    #15print(my_sum(1,2,3,4,5,'6'))    #0print(my_average(1,2,3,4,5))    #3.0print(my_average())     #0

装饰器:

def dec(func):    def in_dec(*args):        if len(args)==0:            return 0        for val in args:            if not isinstance(val,int):                return 0        return func(*args)    return in_dec@dec  def my_sum(*args): #my_sum=in_dec    return sum(args)@decdef my_average(*args):    return sum(args)/len(args)print(my_sum(1,2,3)) #6print(my_average(1,2,3,'1')) #0

装饰器原理分析:

def deco(func):    def in_deco(x,y):        print('in deco')        func(x,y)    print('call deco')    return in_deco   @decodef bar(x,y):    print('in bar',x+y)print(type(bar))bar(1,2)#运行结果call deco<class 'function'>in decoin bar 3

存在@deco ,首先执行 bar = deco(bar)=> in_deco(并把bar添加到 in_deco的属性上 )
即,bar=in_deco
输出:
call deco
< class ‘function’ >

调用bar(1,2) => in_deco(1,2)
执行in_deco(1,2),就会调用到保存在in_deco属性中的bar函数 => bar(1,2)
输出:
in deco
in bar 3