zoukankan      html  css  js  c++  java
  • python装饰器原理和用法总结

    原理

    装饰器本质也是一个函数, 只不过这个函数需要遵循以下规则:

    • 入参只能有一个,类型为函数。 被装饰的函数将入会被传入这个参数
    • 返回值是必须是一个函数, 届时被调用的时候实际上调用的是返回出来的这个函数,所以返回的函数入参通常是
    (*args, **kwargs):
    

    以满足所有函数需要

    之后通过@语法糖即可装饰到任意函数上

    简单装饰器例子

    # 不带参数的装饰器
    def pre_do_sth(func):
        def wrapper(*args, **kwargs):
            print("Do sth before call one")
            func(*args, **kwargs)
        return wrapper
      
    @pre_do_sth
    def echo(msg):
        print(msg)
        
    echo("Hello World")
    

    运行结果

    Do sth before call one
    Hello World
    

    实际上调用的是 wrapper("Hello World") --> echo("Hello World")

    带参数的装饰器例子(参数控制的是装饰器的行为)

    只需要写一个返回 装饰器(入参只有一个, 返回值是一个函数)函数的函数

    同样也能利用@语法糖

    # 带参数的装饰器
    def pre_do_sth_2(msg):
        def decorator(func):
            def wrapper(*args, **kwargs):
                print("Do sth before call two, print:%s"%(msg))
                func(*args, **kwargs)
            return wrapper
        return decorator
    
    
    @pre_do_sth_2("Foo")
    def echo(msg):
        print(msg)
    
    echo("Hello World")
    

    实际上@后面并不是对pre_do_sth_2这个函数生效 而是对pre_do_sth_2的返回值生效

    运行结果

    Do sth before call two, print:Foo
    Hello World
    

    多个装饰器调用顺序

    先声明的装饰器先执行, 即在最外层

    # 不带参数的装饰器
    def pre_do_sth(func):
        def wrapper(*args, **kwargs):
            print("Do sth before call one")
            func(*args, **kwargs)
        return wrapper
    
    # 带参数的装饰器
    def pre_do_sth_2(msg):
        def decorator(func):
            def wrapper(*args, **kwargs):
                print("Do sth before call two, print:%s"%(msg))
                func(*args, **kwargs)
            return wrapper
        return decorator
    
    
    @pre_do_sth
    @pre_do_sth_2("Foo")
    def echo(msg):
        print(msg)
    
    echo("Hello World")
    

    运行结果

    Do sth before call one
    Do sth before call two, print:Foo
    Hello World
    
  • 相关阅读:
    大数据学习相关知识点
    SSMS登记密码清除
    ubuntu 18.04下安装Hadoop
    ubuntu 常见命令整理
    ubuntu 18.04下安装Java
    JQuery ajax请求返回(parsererror)异常处理
    (转载) C/C++编译和链接过程详解 (重定向表,导出符号表,未解决符号表)
    编译器的原理
    笔试题积累
    构造函数为什么不能声明为虚函数
  • 原文地址:https://www.cnblogs.com/Me1onRind/p/12828124.html
Copyright © 2011-2022 走看看