• 装饰器及其应用


    1.写在前面

    1.1为什么要有装饰器(decorator)

      一般在写好的系统中,函数是不允许随便更改的,以免发生不可预见的连环崩溃。但是,随着系统的更新一些必要的功能必须要加到相应的函数中。

    这样的情况下,就需要用到装饰器。装饰器本身也是一个函数,写在目标函数的前面。原理形象地将就是将目标函数装饰一下但是函数本身没变。

    1.2什么是闭包

    1 def outer():
    2     x = 10
    3     def inner():  
    4         print(x)  
    5     return inner   
    6 
    7 f = outer()
    View Code

    上述的代码中inner就是一个闭包。原因有两个:

    (1)它是一个内部的函数

    (2)它引用了encolsing的变量

    那么在运行f()的时候会打印x

    2.装饰器

    有两个函数:

    1 import time
    2 def func1():         
    3     print("func1")
    4     time.sleep(1)
    5 def func2():
    6     print("func2")
    7     time.sleep(2)

    function函数是密封好的两个目标函数,现在想在这两个函数上加上计时功能,且不改变函数。传统方法:

    1 def time_count(func):           
    2     start_time = time.time()    
    3     func()
    4     end_time = time.time()
    5     return print(end_time-start_time)
    6 time_count(func1)

    有了这个count函数就可以直接在function函数上加上计时功能,但是存在的问题是:这个函数改变了调用函数的方式,变为了调用time_count。这样的缺陷在实际生产中部允许的。于是有:

    import time
    def time_count(func):
        def inner():
            ########################################## 装饰器函数
            start_time = time.time()     # 这四行就是添加功能后的功能函数
            func()                       # 此时这四行就是运行后的func1
            end_time = time.time()
            print(end_time-start_time)
            ##########################################
        return inner       # 很关键
    
    @time_count # func1 = time_count(func1)  经过这一步 func1中储存的是inner的地址 并且只有这句会先运行,其他都是函数进内存
    def func1():                         # 功能函数1
        print("func1")
        time.sleep(1)
    
    @time_count
    def func2():
        print("func2")
        time.sleep(2)
    func1()

    代码中注释内容已经很好的展现了装饰器的实现过程。通过@这个方法将function在运行之前已经变成了装饰器函数中的inner函数。

    这里还需要了解解释器在运行时的顺序:三个函数进内存 2 执行第一个@ func1变为inner 执行第二个@。。。 3 执行func()

    3.带参数的装饰器

    带参数装饰器的作用是:根据目标函数的不同需求来在装饰器中执行不同的功能。看下面的例子:页面登陆。

    def para_decorator(f_para_pd):
        def decorator(f_para_dec):
            def func():
                if log_status == True:
                    global source
                    sf = source[f_para_pd]["name"]
                    print("welcome user {kk}".format(kk=sf))
                    f_para_dec()
                if log_status == False:
                    if f_para_pd == "jingdong":
                        info_match(f_para_pd)
                        f_para_dec()
                    elif f_para_pd == "weixin":
                        info_match(f_para_pd)
                        f_para_dec()
                    elif f_para_pd == "qq":
                        info_match(f_para_pd)
                        f_para_dec()
            return func
        return decorator

    这是一个带参数的装饰器的核心内容。该函数有嵌套了三个函数:parameter_decorator 》decorator》func 其实就是在装饰器函数的基础上加上了一层函数。这层函数并没有实际的多少代码。它 的最重要的一个作用就是将一个parameter带入了装饰器中。这样在执行func中的功能中可根据它来调整。

  • 相关阅读:
    android PopupWindow实现从底部弹出或滑出选择菜单或窗口
    AndroidUI开源组件库BottomView 第三方自定义UI控件
    Android LayoutInflater详解
    Android设置上下边框或者左右边框
    杭州驾校模拟考试
    告诉你LTE-FDD与LTE-TDD的区别
    Android-Uiautomator:[5]停止monkey测试
    Android WebView
    解决Item控件抢占焦点
    ACM-计算几何之Quoit Design——hdu1007 zoj2107
  • 原文地址:https://www.cnblogs.com/khal-Cgg/p/5872338.html
Copyright © 2020-2023  润新知