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
    
  • 相关阅读:
    [Bootstrap]7天深入Bootstrap(4)CSS组件
    [Bootstrap]7天深入Bootstrap(3)CSS布局
    [Bootstrap]7天深入Bootstrap(2)整体架构
    [Bootstrap]7天深入Bootstrap(1)入门准备
    如何快速给自己博客增加10000推荐量
    [Test] 单元测试艺术(2) 打破依赖,使用模拟对象,桩对象,隔离框架
    C#如何使用ES
    异步tcp通信——APM.Server 消息推送服务的实现
    异步tcp通信——APM.ConsoleDemo
    异步tcp通信——APM.Core 解包
  • 原文地址:https://www.cnblogs.com/Me1onRind/p/12828124.html
Copyright © 2011-2022 走看看