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
    
  • 相关阅读:
    Flexigrid在IE下不显示数据的处理
    [置顶] ios 网页中图片点击放大效果demo
    WPF仿360卫士9.0界面设计
    Android调用相机并将照片存储到sd卡上
    Android 将文件保存到SD卡,从卡中取文件,及删除文件
    java 正则表达式学习
    linux下的块设备驱动(一)
    已知用经纬度表示的两点,求两点之间的直线距离
    IndiaHacks 2016
    IndiaHacks 2016
  • 原文地址:https://www.cnblogs.com/Me1onRind/p/12828124.html
Copyright © 2011-2022 走看看