一个通用的运行时间装饰器
一个 时间 运行 通用 装饰
2023-06-13 09:11:41 时间
这个装饰器只解决一个问题:“这个程序中这个函数运行需要多久?”
最近在用 Python3 写一个程序,功能已经实现了,但是运行速度太慢了,慢到令人发指,为了让这个程序的存在具有意义,我需要把这些功能函数耗费的时间大概了解,找出那些运行时间比较长的,之后有针对性地解决
所以,获取程序中各函数运行时间成了当务之急,这里涉及两个小困难:
- 函数众多,在每个函数中都加上计算时间的代码会很繁琐,最后还得删除 这个解决起来不难,用装饰器就可以解决,不需要修改代码
- 函数绝大多数都定义在类中,这样普通的运行时间装饰器就会产生不兼容的情况 所以就有了下面这个通用装饰器
import datetime
import wrapt
import inspect
# 通用时间装饰器
@wrapt.decorator
def universal(wrapped, instance, args, kwargs):
if instance is None:
if inspect.isclass(wrapped):
# 装饰一个类
# Decorator was applied to a class.
return wrapped(*args, **kwargs)
else:
# 装饰一个普通函数或者静态方法
# Decorator was applied to a function or staticmethod.
ret = consume_time(wrapped=wrapped, args=args, kwargs=kwargs)
return ret
else:
if inspect.isclass(instance):
# 装饰类方法
# Decorator was applied to a classmethod.
ret = consume_time(wrapped=wrapped, args=args, kwargs=kwargs)
return ret
else:
# 装饰实例方法
ret = consume_time(wrapped=wrapped, args=args, kwargs=kwargs)
return ret
def consume_time(wrapped, args, kwargs):
local_time = datetime.datetime.now()
ret = wrapped(*args, **kwargs)
times = (datetime.datetime.now() - local_time).seconds
funcname = wrapped.__name__
print('运行 {} 函数消耗的时间为 {} 分 {} 秒'.format(
funcname, times // 60, times % 60))
# print('Run {} time is {} minutes {} seconds'.format(
# funcname, times // 60, times % 60))
return ret
既然说是通用装饰器,怎么个通用法呢?它可以作用于以下内容
- 类
- 普通函数
- 类静态方法
- 类方法
- 实例方法
接下来我们测试一下
【未加装饰器的程序】
import time
class People:
# 定义基本属性
name = ""
age = 0
# 初始化函数
def __init__(self, name, age):
self.name = name
self.age = age
# 静态方法
@staticmethod
def work():
time.sleep(3)
print("I could work")
# 类方法
@classmethod
def speak(cls, words):
time.sleep(1)
print(words)
# 实例方法
def eat(self, food):
time.sleep(5)
print(f"I am eating {food}")
# 普通函数
def read(bookname):
time.sleep(1)
print(f"I am reading {bookname}")
# 调用普通函数
read("《Linux 二进制分析》")
# 调用静态方法
People.work()
# 调用类方法
People.speak("hello world")
## 调用实例方法
# 实例化一个对象
xiaoming = People(name="xiaoming", age=18)
xiaoming.eat("a sandwich")
运行后结果
现在我们加上时间装饰器,来看看这些函数都消耗了多少时间
【已经加上装饰器的程序】
为了演示装饰不同内容,我们给装饰器每个分支都加上 print
import datetime
import time
import wrapt
import inspect
@wrapt.decorator
def universal(wrapped, instance, args, kwargs):
funcname = wrapped.__name__
if instance is None:
if inspect.isclass(wrapped):
print("-" * 50)
print("正在装饰一个类")
return wrapped(*args, **kwargs)
else:
print("-" * 50)
print(f"正在装饰一个普通函数或者静态方法: {funcname}")
ret = consume_time(wrapped=wrapped, args=args, kwargs=kwargs)
return ret
else:
if inspect.isclass(instance):
print("-" * 50)
print(f"正在装饰类方法: {funcname}")
ret = consume_time(wrapped=wrapped, args=args, kwargs=kwargs)
return ret
else:
print("-" * 50)
print(f"正在装饰实例方法: {funcname}")
ret = consume_time(wrapped=wrapped, args=args, kwargs=kwargs)
print("-" * 50)
return ret
def consume_time(wrapped, args, kwargs):
local_time = datetime.datetime.now()
ret = wrapped(*args, **kwargs)
times = (datetime.datetime.now() - local_time).seconds
funcname = wrapped.__name__
print('运行 {} 函数消耗的时间为 {} 分 {} 秒'.format(
funcname, times // 60, times % 60))
# print('Run {} time is {} minutes {} seconds'.format(
# funcname, times // 60, times % 60))
return ret
@universal
class People:
# 定义基本属性
name = ""
age = 0
# 初始化函数
def __init__(self, name, age):
self.name = name
self.age = age
# 静态方法
@universal
@staticmethod
def work():
time.sleep(3)
print("I could work")
# 类方法
@universal
@classmethod
def speak(cls, words):
time.sleep(1)
print(words)
# 实例方法
@universal
def eat(self, food):
time.sleep(5)
print(f"I am eating {food}")
# 普通函数
@universal
def read(bookname):
time.sleep(1)
print(f"I am reading {bookname}")
# 调用普通函数
read("《Linux 二进制分析》")
# 调用静态方法
People.work()
# 调用类方法
People.speak("hello world")
## 调用实例方法
# 实例化一个对象
xiaoming = People(name="xiaoming", age=18)
xiaoming.eat("a sandwich")
运行后结果
我们可以直观地看到, eat
这个函数运行时间最长,运行时间为 5 秒,可能需要我们针对性解决
如果你不想复制装饰器文件,可以直接从以下百度云链接中下载
https://pan.baidu.com/s/1mO9W2QGeJRp8qNjWzelUvw 提取码: ajp4
相关文章
- Python 学生信息管理系统——文章中源码100%真实有效—–如何将类、初始化属性、模块、循环判断、静态方法等一系列知识点结合起来做一个项目「建议收藏」
- electron+vue从0到1实现一个桌面端日期时间倒计时软件实践(持续更新)
- element-plus 一个vue3.xUI框架 (element-ui的3.x 版初体验)
- 请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构
- C语言 爱心代码_用c语言编辑一个爱心
- 2022-09-27:给定一个棵树,树上每个节点都有自己的值,记录在数组nums里,比如nums[4] = 10,表示4号点的值
- 40 行 Python 代码,写一个 CPU!
- 前Twitter工程师爆料:“2015 年,我曾被要求构建一个最不道德的东西!”
- 「Go工具箱」推荐一个轻量级、语义化的时间处理库:carbon
- Java 实现定时删除 一个文件夹下不是当前时间文件夹的 其他文件夹里面的数据
- Java 多个任务@Scheduled 里面的时间一样,有一个方法就不走了,这个咋解决
- 深度学习的下一个十年,延展基础科学研究变革的「角力场」
- oracle时间的获取,前一天,上一个星期,上一个月详解数据库
- 一个简单的Java MVC模式示例详解编程语言
- MySQL:一个值得重视的数据库平台回顾(mysql一段时间)
- Oracle时区调节:增加一小时实现准确时间管理(oracle加一个小时)
- MySQL时间对比:一个实战性的比较(mysql对比时间)
- MSSQL查询当前时间小时:一个实例(mssql查询当前小时)
- 统计Oracle出现次数统计一个数据洞察之旅(oracle出现个数)
- 用Redis阻塞一个线程,创建一种新的处理方式(redis阻塞一个线程)
- Oracle构建一个更美好的昨天(oracle 一年前时间)
- 听说现在有个AR APP很火,所以我也做了一个
- 一个防止被采集的方法
- 一个能对访问者进行编号、记录访问次数、IP、时间的统计制作实例
- 学习YUI.Ext第七日-View&JSONViewPartTwo-一个画室网站的案例
- PHP一个页面执行时间类代码
- 一个日期下拉菜单的js实现代码
- 在yii中新增一个用户验证的方法详解
- 一个简单的JS时间控件示例代码(JS时分秒时间控件)
- 一个判断抢购时间是否到达的简单的js函数