首页 > 代码库 > python 学习笔记7(装饰器)

python 学习笔记7(装饰器)

闭包(closure)是函数式编程的重要的语法结构。

  定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).

def outer():                                   x = 1                                        def inner():                                               print(x)                                         return inner                               f = outer()                                f()                  

 

inner就是内部函数,inner里引用了外部作用域的变量x(x在外部作用域outer里面,不是全局作用域),则这个内部函数inner就是一个闭包。

技术分享

闭包=函数块+定义函数时的环境,inner就是函数块,x就是环境。

装饰器

  装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。

  它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能

简单的装饰器函数:

@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作

import timedef shoe_time(f):    def inner():        start = time.time()        f()        end = time.time()        print(end-start)    return inner@shoe_time   #foo = shoe_time(foo)def foo():    #start = time.time()    print("foo......")    time.sleep(2)    #end = time.time()    #print(end-start)               #2.0001144409179688#foo()@shoe_time     #bar = shoe_time(bar)def bar():    # start = time.time()    print("bar......")    time.sleep(3)    #end = time.time()    #print(end-start)                #3.001171588897705#bar()#shoe_time(foo)              #2.0001142024993896#shoe_time(bar)                #3.001171588897705foo()                      #foo......                           # 2.0001144409179688bar()                       # bar......                          # 3.00017142295837

技术分享

 

带参数的被装饰函数

#功能函数加参数import timedef shoe_time(f):     def inner(x,y):         start = time.time()         f(x,y)         end = time.time()         print(end-start)     return inner@shoe_timedef add(a,b):    print(a+b)    time.sleep(3)#@shoe_time# def foo():#     print("foo......")#     time.sleep(2)# @shoe_time# def bar():#      print("bar......")#      time.sleep(3)#add(1,3)       #4               #3.000171661376953#不定长参数import timedef shoe_time(f):     def inner(*x,**y):         start = time.time()         f(*x,**y)         end = time.time()         print(end-start)     return inner@shoe_timedef add(*a,**b):    sum = 0    for i in a:        sum += i    print(sum)    time.sleep(3)#@shoe_time# def foo():#     print("foo......")#     time.sleep(2)# @shoe_time# def bar():#      print("bar......")#      time.sleep(3)#add(1,3,4,6,78)              #92                             #3.000171661376953

带参数的装饰器

  装饰器还有更大的灵活性,例如带参数的装饰器:在上面的装饰器调用中,比如@shoe_time,该装饰器唯一的参数就是执行业务的函数。装饰器的语法允许我们在调用时,提供其它参数,比如@decorator(a)。这样,就为装饰器的编写和使用提供了更大的灵活性。

#带参数的装饰器import timedef logger(flag=""):    def shoe_time(f):         def inner(*x,**y):             start = time.time()             f(*x,**y)             end = time.time()             print(end-start)             if flag == "true":                 with open("日志记录", "a",encoding="utf8") as g:                     g.write("值为: %s 时间为: %s\n"%(f(*x),(end-start)))         return inner    return shoe_time@logger("true")     #@show_timedef add(*a,**b):    Sum = 0    for i in a:        Sum += i    print(Sum)    time.sleep(3)    return Sum@logger("abc")def foo():    print("foo......")    time.sleep(2)# @shoe_time# def bar():#     print("bar......")#     time.sleep(3)add(1,3,4,6,78)      #92                    #3.000171661376953foo()

  @logger("true") 做了两件事:

    (1)@ogger("true"):得到闭包函数show_time,里面保存环境变量flag

    (2)@time   :add=show_time(add)

上面的logger是允许带参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器(一个含有参数的闭包函数)。当我 们使用@logger("true")调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中。

 

 

 

 

 

 

 

 

 

 

 

 

 

python 学习笔记7(装饰器)