zoukankan      html  css  js  c++  java
  • 【python】装饰器Decorator

    装饰器:

    定义:本质是函数,为其他函数添加附加功能。

    原则:1.不能修改被装饰的函数的源代码

              2.不能修改被装饰函数的调用方式

    实现装饰器的知识储备:装饰器=高阶函数+嵌套函数

    1.函数即变量

    2.高阶函数

    a:把一个函数名当做实参传给另一个函数---->为了不能修改被装饰的函数的源代码,为函数增加功能
    b:返回值中包含函数名------>为了不能修改被装饰函数的调用方式

    3.嵌套函数

      a.嵌套函数即在函数内部定义函数并使用

      b.外部函数的变量可以被内部函数所使用,但不能被内部函数修改,若要修改需要添加关键字nonlocal

    def foo():
        outer_name="foo"
        print("in the foo")
        def bar():
            nonlocal outer_name
            outer_name="bar"  ##若不声明nonlocal,就无法修改外部的变量
            print("in the bar")
        bar()#函数内部定义函数并使用
        print("the outer_name is {_out_name}".format(_out_name=outer_name))
    
    foo()
    >>>in the foo
    >>>in the bar
    >>>the outer_name is bar
    

     装饰器语法总结:

    def myDecorator(...):  # 定义装饰器,可能带参数
        def decorator(func):  # 装饰器核心,以被装饰的函数对象为参数,返回装饰后的函数对象
            def wrapper(*args, **kvargs):  # 装饰的过程,参数列表适应不同参数的函数
                ...  # 修改函数调用前的行为
                func(*args, **kvargs)  # 调用函数
                ...  # 修改函数调用后的行为
    
            return wrapper
        return decorator
    
    
    @myDecorator(...):      # 给函数加上装饰器
    def myFunc(...):   # 自己定义的功能函数

    不带参数的装饰器:

    import time
    def timer(func): #timer(test1)  func=test1  用于把被装饰函数传递给装饰器
        def deco(*args,**kwargs):   ##用于实现装饰器功能,附加功能
            start_time=time.time()
            func(*args,**kwargs)   #run test1()
            stop_time = time.time()
            print("the func run time  is %s" %(stop_time-start_time))
        return deco  ##返回被装饰函数的地址,这样就保持了原有的调用方式
    @timer  #test1=deco=timer(test1)
    def test1():
        time.sleep(1)
        print('in the test1')
    
    @timer # test2 = deco=timer(test2)    test2(name) =deco(name)
    def test2(name,age):
        time.sleep(1)
        print("test2:",name,age)
    
    test1()
    test2("paul",22)
    

     

    带参数的装饰器:

    import time
    
    def time_log(log_type):##用于定义参数
        """
        timer为装饰器的核心代码
        """
        def timer(func): #timer(test1)  func=test1  用于把被装饰函数传递给装饰器
            def deco(*args,**kwargs):   ##用于实现装饰器功能,附加功能
                start_time=time.time()
                func(*args,**kwargs)   #run test1()
                stop_time = time.time()
                if log_type=="auto":
                    print("the func auto run time  is %s" %(stop_time-start_time))
                elif log_type=="manual":
                    print("the func manual run time  is %s" % (stop_time - start_time))
            return deco  ##返回被装饰函数的地址,这样就保持了原有的调用方式
        return  timer
    
    
    @time_log(log_type="auto")
    def test1():
        time.sleep(1)
        print('in the test1')
    
    @time_log(log_type="manual")
    def test2(name,age):
        time.sleep(1)
        print("test2:",name,age)
    
    test1()
    test2("paul",22)
    

      

  • 相关阅读:
    C#实现函数超出指定时间,自动退出
    批量下载github代码,同时含有解压zip,遍历文件函数
    MSBuild构建工作空间,解决project.Documents.Count()=0的问题
    使用Roslyn 使用MSBuild进行编译,项目不报错,但是运行显示ReflectionTypeLoadException,解决方案
    基于roslyn实现函数与函数之间的依赖关系
    discount C#
    对Symbol的获取(Roslyn)
    AcWing 955. 维护数列(splay插入,删除,区间修改,区间翻转,区间求和,区间求最大子段和)
    AcWing 1063. 永无乡(并查集, 启发式合并,splay)
    AcWing 2437. Splay
  • 原文地址:https://www.cnblogs.com/paulwinflo/p/12259331.html
Copyright © 2011-2022 走看看