zoukankan      html  css  js  c++  java
  • 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 time
    def 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.001171588897705
    foo()                      #foo......                           # 2.0001144409179688
    bar()                       # bar......
                              # 3.00017142295837

    带参数的被装饰函数

    #功能函数加参数
    import time
    def shoe_time(f):
         def inner(x,y):
             start = time.time()
             f(x,y)
             end = time.time()
             print(end-start)
         return inner
    @shoe_time
    def 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 time
    def shoe_time(f):
         def inner(*x,**y):
             start = time.time()
             f(*x,**y)
             end = time.time()
             print(end-start)
         return inner
    @shoe_time
    def 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 time
    def 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
    "%(f(*x),(end-start)))
             return inner
        return shoe_time
    @logger("true")     #@show_time
    def 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.000171661376953
    foo()

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

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

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

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

     
  • 相关阅读:
    jquery map.js
    json序列指定名称
    如何将后台传来的json反序列化为前端具体对象
    创建随机码!!
    用户(三次)登录--作业小编完成
    求出1-2+3-4+5------100求和
    if -else 条件语句原理
    联系:中奖彩票小编译
    求出1-100内所有奇数。
    练习题:求1-100所有数偶数
  • 原文地址:https://www.cnblogs.com/lst1010/p/5851643.html
Copyright © 2011-2022 走看看