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)
    

      

  • 相关阅读:
    动态生成 Excel 文件供浏览器下载的注意事项
    JavaEE 中无用技术之 JNDI
    CSDN 泄露用户密码给我们什么启示
    刚发布新的 web 单点登录系统,欢迎下载试用,欢迎提建议
    jQuery jqgrid 对含特殊字符 json 数据的 Java 处理方法
    一个 SQL 同时验证帐号是否存在、密码是否正确
    PostgreSQL 数据库在 Windows Server 2008 上安装注意事项
    快速点评 Spring Struts Hibernate
    Apache NIO 框架 Mina 使用中出现 too many open files 问题的解决办法
    解决 jQuery 版本升级过程中出现 toLowerCase 错误 更改 doctype
  • 原文地址:https://www.cnblogs.com/paulwinflo/p/12259331.html
Copyright © 2011-2022 走看看