zoukankan      html  css  js  c++  java
  • 6.4、装饰器


    装饰器:

    意义:在不能改变原函数的源代码,和在不改变整个项目中原函数的调用方式的情况下,给函数添加新的功能

    由于不允许改变函数的源代码,在忽略调用方式的情况下,我们可能会有以下结果:

    def decorator(func):
        func()
        print("logging")
    
    def test1():
        print("test1")
    
    def test2():
        print("Test2")
    
    decorator(test1)
    decorator(test2)

    但这改变了原本的调用方式,原本是test1(),现在是decorator(test1)

    那么如果我们为了使调用方式不变,是否可以使装饰好的函数decorator的返回值是一个我们需要的函数,再赋值给原来的函数名呢?

    于是:

    def timmer1(func):
        def warpper():
            start_time = time.time()
            func()
            stop_time=time.time()
            print("the func run time is %s"%(stop_time-start_time))
         return warpper
    
    test3=timmer1(test3)

    好像上面这段代码并没有改变原来的调用方式,调用原来的test3,相当于运行timmer1中的warpper

    如果对于无参数的函数来说,上面的代码已经实现了我们的目的,但对于带参数的函数,上面的代码没有传入参数,所以仍然需要修改

    于是:

    def timmer2(func):
        def warpper(*args,**kwargs):
            start_time = time.time()
            func(*args,**kwargs)
            stop_time=time.time()
            print("the func run time is %s"%(stop_time-start_time))
        return warpper

    在上上面的代码中,由于实质上,test3已经等于wrapper,所以可以直接使用,test3(参数)来传入参数,为了处理参数不确定数量问题,可以使用可变长度参数

    上面代码还存在一个问题,无法获取原本函数中的返回值,那么我们还需要加上一些东西:

    import time
    def timmer2(func):
        def warpper(*args,**kwargs):
            start_time = time.time()
            res=func(*args,**kwargs)
            return res
            stop_time=time.time()
            print("the func run time is %s"%(stop_time-start_time))
        return warpper

    使用一个变量记录下原函数的返回值。

    这样我们就实现了装饰器的基本功能。


    补充:

    python提供了一个功能:

    @装饰器名
    def 目标装饰函数名():
        pass
    #上面的效果是 目标装饰函数名=装饰器(目标装饰函数名)

    所以在需要替换原函数的时候,可以在目标装饰函数定义的上一行加上@装饰器名

    所以上面的代码会变成:

    def timmer2(func):
        def warpper(*args,**kwargs):
            start_time = time.time()
            func(*args,**kwargs)
            stop_time=time.time()
            print("the func run time is %s"%(stop_time-start_time))
        return warpper
    
    @timmer2
    def test7():
        print("test7")
        
    @timmer2
    def test6(x):
        print(x)
    
    test7()
    test6(2)
    import time
    def timmer2(func):
        def warpper(*args,**kwargs):
            start_time = time.time()
            res=func(*args,**kwargs)
            return res
            stop_time=time.time()
            print("the func run time is %s"%(stop_time-start_time))
        return warpper
    
    @timmer2
    def test4():
        print("test4 run")
        return "test4 done"
    test4()
    
    print("--------")
    print(test4())

    第二个补充:

    可以一个函数,可以使用多个装饰器

    比如:

    @装饰器1

    @装饰器2


  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/progor/p/8410776.html
Copyright © 2011-2022 走看看