• 如何理解python中的装饰器, 这篇文章就够了!


    1. python中的函数

    • 理解裝飾器之前先要理解閉包, python中閉包的出現是因爲函數在python中也是一個對象, 也可以被引用, 然後調用, 比如
    def log():
        print('我是一些log信息')
    
    
    if __name__ == '__main__':
        print(type(log))
        log_func = log
        log_func()
    
    • 執行結果如下
    <class 'function'>
    我是一些log信息
    
    • 可以看到log函數是一個對象, 可以被賦值給log_func, log_func可以像函數一樣被執行

    2. python中的闭包

    • 理解了python也是一個函數, 我們看看閉包, 閉包就是函數裏面返回了一個函數, 第二層嵌套函數還可以引用第一層函數的局部變量, 相當於嵌套函数引用了这个变量,将这个局部变量封闭在了嵌套函数中, 這樣的結構叫做閉包, 比如
    def log():
        log_info = '我是一些log信息'
    
        def wrapper():
            print(log_info)
            print('我是函數wrapper實現的功能')
            
    
        return wrapper
    
    
    if __name__ == '__main__':
        f = log()()
    
    • 函数log()执行结果是一个wrapper函数对象, log()后面再加一个()调用就是wapper函数, 返回打印结果如下:
    我是一些log信息
    我是函數wrapper實現的功能
    

    3. python中的装饰器

    • 理解了闭包, 我们看看装饰器, 装饰器可以看成一个"自动"帮我们执行的闭包, 它的作用是能帮我们的函数或者类在不改变原有功能代码的前提下额外增加一些功能
    import functools
    
    
    def log(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print('name参数是: {}'.format(*args))
            print('我在函数%s()被调用前做了一些事情' % func.__name__)
            print('调用函数 %s():' % func.__name__)
            return func(*args, **kwargs)
    
        return wrapper
    
    
    @log
    def get_user_info(name):
        print('函数{}的执行结果是: 获取到用户{}的信息'.format(get_user_info.__name__, name))
    
    
    if __name__ == '__main__':
        get_user_info('XiaoMing')
    
    
    • 执行结果如下:
    name参数是: XiaoMing
    我在函数get_user_info()被调用前做了一些事情
    调用函数 get_user_info():
    函数get_user_info的执行结果是: 获取到用户XiaoMing的信息
    
    • log函数是一个闭包, 传入的参数是一个函数, 并且函数的参数被一层层嵌套函数传递下去
    • @语法帮我们做的事情就是"自动"执行这个闭包函数到最后一层, 也就是到wrapper函数这一层, 相当于是
      get_user_info = log(get_user_info('XiaoMing'))()
    • 当我们调用get_user_info函数时候, 我们并不是调用我们写的函数, 而是log闭包函数里面的wrapper函数, 然后wrapper的返回结果会真正调用我们写的get_user_info函数
    • @functools.wraps(func)这段代码的意思就是将原函数get_user_info的元信息(docstring、name、参数列表)拷贝到装饰器里面的wrapper函数中
    • 这样@log这个装饰器就帮我们实现了在不改变原有代码的基础上额外增加了get_user_info这个函数的功能
    我在想我要不要写一句励志的话......
  • 相关阅读:
    MySQL数据库06 /数据库总结
    数据库05 /索引、数据库备份、锁和事务、慢查询优化、索引命中相关
    数据库04 /多表查询、pymysql模块
    数据库03 /库、表、记录的详细操作、单表查询
    struts基于ognl的自动类型转换需要注意的地方
    struts-json-plugin result中配置对象的序列化
    hibernate关联关系笔记
    使用动态代理实现数据库事务(转)
    xml、文件操作功能类
    将CachedRowSet中的数据转储到对象中
  • 原文地址:https://www.cnblogs.com/iread9527/p/12549205.html
Copyright © 2020-2023  润新知