闭包和装饰器

闭包:延伸了作用域的函数,包含函数定义体中引用,但是不在定义体中定义的非全局变量。
有3个要素——
1:嵌套函数;2:内部函数引用了外部函数的局部变量;3:外部函数的返回值是内部函数的引用。
# 例子,来自《流畅的python》
def make_averager():
    series=[]
    def averager(new_value):
        series.append(new_value)
        avg = sum(series)/len(series)
        return avg
    return averager
#------------------------------------------
avg = make_averager()
s1 = avg(10)
print(s1)
s2 = avg(11)
print(s2)
s3 = avg(12)
print(s3)
装饰器的2个特性——
1:把被装饰的函数替换成其他函数;2:装饰器在加载模块时立即执行。
被装饰的函数的定义体和调用方式不会发生改变。
#例子1:
import time

def outer(func):
    def wrapper():
        print('i am inner')
        print('start time is :' + str(time.time()))
        func()
        print('end time is :' + str(time.time()))
    # 装饰器加载时执行,所以会最先打印。
    print('i am outer')
    return wrapper

@outer
def foo():
    print('foo......')
    time.sleep(3)

foo()
print(foo) #foo的类型是outer的返回值
# 例子2:多层装饰,本质相当于层层装饰:deco2(deco1(foo))
def deco1(func): print('func 1 in') def wrapper1(): print('wrap1 in') func() print('wrap1 out') print('func 1 out') return wrapper1 def deco2(func): print('func 2 in') def wrapper2(): print('wrap2 in') func() print('wrap2 out') print('func 2 out') return wrapper2 @deco1 @deco2 def foo(): print('foo')
# 例子3,带参数的装饰器。
#
带参数的装饰器 def deco(params): # params 为需要传入的参数 print('floor1') def inner(func): print('floor2') def warp(*args, **kwargs): print('floor3') print('装饰开始') for i in range(params): func(*args, **kwargs) print('装饰结束') print('out3') print('out2') return warp print('out1') return inner @deco(5) # 这个就是生成一个函数warp指向demo def demo(): print('ok') demo()

 



posted @ 2020-06-28 13:45  muyue123  阅读(160)  评论(0编辑  收藏  举报