python 装饰器(Decorators)介绍

2019-03-22  本文已影响0人  别动我名字呀
为什么要装饰器

假设现在程序实现了say_hello()say_goodbye()两个函数。

import time
def say_hello():
    time.sleep(1)
    print("say_hello!")


def say_goodbye():
    time.sleep(1)
    print("say_goodbye!") # bug here

if __name__ == '__main__':
    say_hello()
    say_goodbye()

这时候我们需要知道每个方法从开始到结束花了多常时间要怎么实现呢

好,小A他是这样实现的。

import time

def say_hello():
    start_time=time.time()
    time.sleep(1)
    print("say_hello!")
    end_time=time.time()
    print(end_time-start_time)

def say_goodbye():
    start_time=time.time()
    time.sleep(1)
    print("say_goodbye!")
    end_time=time.time()
    print(end_time-start_time)

if __name__ == '__main__':
    say_hello()
    say_goodbye()

# 输出结果:
#say_hello!
#1.0002422332763672
#say_goodbye!
#1.0095882415771484

这样需求就实现了,不过在现实生活中多方法都是很久之前写的,这样改动代码说不定就埋下了坑,那我们如何做到不改变现有的函数,去实现新功能呢

这时候就是装饰器登场表现的时候了

# author:PicaHealth
# contact: 172212595@qq.com
# datetime:2019/3/22 22:02
# software: PyCharm

"""
文件说明: 计时装饰器

"""

import  time
def decorator(func):# 这里需要了解如何将函数做为一阶参数
    """
    这是个计时装饰器
    """
    def wrapper(*args,**kwargs): #这里需要了解可变参数
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time-start_time)
    return wrapper

# 这里相当于把整个say_hello的内存地址当做参数传给了decorator(),在wrapper方法中的func()方法等于在调用say_hello()
@decorator 
def say_hello():
    time.sleep(1)
    print("say_hello!")

#只需要在函数的定义前加上@和装饰器的名称
@decorator
def say_goodbye():
    time.sleep(1)
    print("say_goodbye!")


if __name__ == '__main__':
    say_hello()
    say_goodbye()


# 输出结果:
#say_hello!
#1.0002422332763672
#say_goodbye!
#1.0095882415771484

总结:

装饰器本质上是一个Python函数,它可以让其他函数在不修改任何代码的前提下增加额外功能。
本质是先运行装饰器,把函数当做参数传过去,在装饰器内部调用函数
它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

如果对以上代码原理还是不了解需要先看一下:高级函数+嵌套函数
更多细节参考:python 使用装饰器处理日志

上一篇下一篇

猜你喜欢

热点阅读