博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 装饰器
阅读量:4958 次
发布时间:2019-06-12

本文共 4207 字,大约阅读时间需要 14 分钟。

直接进入主题

原代码

以下是原代码,要求给改代码添加统计时间功能

 

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

版本1(直接在原函数上修改)

可能有的同学就做出了下面这个版本

import timedef say_hello():    start_time=time.time()    time.sleep(1)    print("Hi!")    stop_time=time.time()    print('该函数运行时间为:%s' %(stop_time-start_time))say_hello()#输出:# Hi!# 该函数运行时间为:1.0008747577667236

  该版本存在的问题

  1. 直接修改了函数的原始内容
  2. 当如果有第二个函数需要实现相同的功能是,需要重新做一遍重复的工作

版本2(将函数当做参数传入)

  经过修改上面的版本我们做出了新的代码

import timedef run_time(func):    start_time=time.time()    func()    stop_time=time.time()    print('该函数运行时间为:%s' %(stop_time-start_time))def say_hello():    time.sleep(1)    print("Hi!")run_time(say_hello)

 

  该版本通过定义一个新的函数 run_time ,然后再新函数中调用原来的函数,实现计算函数的运行时间功能

  但是该版本有个问题就是修改了原函数的调用方式,这样很不好。

版本3(修改原函数的内容)

import timedef run_time(func):    def wrapper():        start_time=time.time()        func()        stop_time=time.time()        print('该函数运行时间为:%s' %(stop_time-start_time))    return  wrapperdef say_hello():    time.sleep(1)    print("Hi!")say_hello=run_time(say_hello)say_hello()

  于是乎我们就有了以上的新代码,该代码即没有修改原函数,也没有修改函数的调用方式。

  巧妙的通过返回函数 wrapper ,在 执行say_hello=run_time(say_hello)  这句代码将 say_hello 的内容修改。

  这基本上算是Python中装饰器的基本架子了。

  再把  say_hello=run_time(say_hello)  这句代码优化下就变为下面的版本了。

版本4(关键词@)

import timedef run_time(func):    def wrapper():        start_time=time.time()        func()        stop_time=time.time()        print('该函数运行时间为:%s' %(stop_time-start_time))    return  wrapper@run_time #  这句代码等同于  say_hello=run_time(say_hello)def say_hello():    time.sleep(1)    print("Hi!")say_hello()

 

  这个版本的代码算是一个装饰器了,但是我们又有了一个问题,上面的原函数是没有参数,没有返回值的,如果有参数有返回值又该怎么解决呢?请看下一个版本代码

版本5(原函数带有参数、返回值时的实现)

  这个版本通过修改 wrapper 函数的参数,并将参数传入 run_time 中传入的 func 函数中,实现了带有参数的调用。

  并给wrapper 函数添加 func 函数执行后的返回值。完美实现了需求。

import timedef run_time(func):    def wrapper(*args, **kwargs):        start_time = time.time()        res = func(*args, **kwargs)        stop_time = time.time()        print('该函数运行时间为:%s' % (stop_time - start_time))        return res    return wrapper@run_time  # 这句代码等同于  say_hello=run_time(say_hello)def say_hello(name):    time.sleep(1)    print(name, ":Hi!")    return "我是返回值"print(say_hello("Oliver"))# Oliver :Hi!# 该函数运行时间为:1.000196933746338# 我是返回值

 

  现在问题又来了,如果某些函数需要直接输出运行时间,而某些函数需要将运行时间写入文件又该怎么处理呢?

版本6(装饰器函数需要参数时实现)

  当然有的同学可能会说就写两个装饰器函数呗,但是因为装饰器函数实现的功能基本一致,而如果能想办法给装饰器函数添加一个参数就完美解决这个问题了。请看以下代码

import timedef run_time(type):    def deco(func):        def wrapper(*args, **kwargs):            start_time = time.time()            res = func(*args, **kwargs)            stop_time = time.time()            content = '该函数运行时间为:%s' % (stop_time - start_time)            if type == "print":                print(content)            elif type == "write_file":                with open("运行时间记录", "a+", encoding='utf8') as f:                    f.write(                        '{0} {1}:{2}\r\n'.format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), func.__name__,                                                 content))            return res        return wrapper    return deco@run_time("print")  #这段代码相当于 say_hello= run_time("print")(say_hello) ---》也就是  say_hello= deco(say_hello)def say_hello(name):    time.sleep(1)    print(name, ":Hi!")    return "我是返回值"@run_time("write_file")def say_hello2(name):    time.sleep(1)    print(name, ":你好!")    return "我是say_hello2返回值"print(say_hello("Oliver"))print(say_hello2("张三"))# 输出:# Oliver :Hi!# 该函数运行时间为:1.0008816719055176# 我是返回值# 张三 :你好!# 我是say_hello2返回值# 文件内容:# 2018-08-03 10:54:37 say_hello2:该函数运行时间为:1.0004534721374512

版本7(一个函数多个装饰器)

  当然一个函数也是可以添加多个装饰器的。比如添加验证功能,并且计算函数运行时间。执行的顺序也是从下往上执行的

如下代码:

import timedef verify(func):    def wrapper(*args, **kwargs):        print("验证一些信息···")        res = func(*args, **kwargs)        return res    return wrapperdef run_time(func):    def wrapper(*args, **kwargs):        start_time = time.time()        res = func(*args, **kwargs)        stop_time = time.time()        print('该函数运行时间为:%s' % (stop_time - start_time))        return res    return wrapper@verify@run_timedef say_hello(name):    time.sleep(1)    print(name ,":Hi!")say_hello('Oliver')#输出:# 验证一些信息···# Oliver :Hi!# 该函数运行时间为:1.0001380443572998

 

 

 

转载于:https://www.cnblogs.com/haowuji/p/9412968.html

你可能感兴趣的文章
DataTable和 DataRow的 区别与联系
查看>>
检索COM 类工厂中CLSID 为 {00024500-0000-0000-C000-000000000046}的组件时失败
查看>>
mysql数据库中数据类型
查看>>
Fireworks基本使用
查看>>
两台电脑间的消息传输
查看>>
Linux 标准 I/O 库
查看>>
.net Tuple特性
查看>>
Java基础常见英语词汇
查看>>
iOS并发编程笔记【转】
查看>>
08号团队-团队任务5:项目总结会
查看>>
SQL2005 删除空白行null
查看>>
mysql备份与恢复
查看>>
混沌分形之迭代函数系统(IFS)
查看>>
边框圆角Css
查看>>
使用Busybox制作根文件系统
查看>>
jpg图片在IE6、IE7和IE8下不显示解决办法
查看>>
delphi之模糊找图
查看>>
Javascript模块化编程的写法
查看>>
大华门禁SDK二次开发(二)-SignalR应用
查看>>
oracle 使用job定时自动重置sequence
查看>>