python | 手写一个python代码计时器,分别基于装饰器和上下文管理器两种方案实现

2023-09-22 14:57:09


01 传统方案

我们在编码的时候常常有函数计时的需求,通常都是直接使用python自带的time库来实现。

import time

t0 = time.time()
...  # 要计时的代码
elapsed = time.time() - t0
print(f"耗时{elapsed}s")

这种方式显然不够优雅。

02 使用函数装饰器

装饰器很适合用于给函数计时,只需要在函数定义时,函数的上方使用装饰器,就能实现对函数的计时,随用随写。

import time
from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
		t0 = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - t0
        print(f"耗时{elapsed}s")
        return result
    return wrapper

使用时:

@timer
def do_something():
	...

do_something()  # 执行函数时自动执行装饰器中代码 显示该函数的耗时

03 使用上下文管理器

装饰器的好处是对函数本身的代码无侵入,但仅适用于函数的情形,而且如果一个函数上已经有其他装饰器,再叠加装饰器可能会有潜在的问题。此时的另一种方案是使用上下文管理器,配合with关键字实现计时功能。

创建一个用于计时的上下文管理器:

import time

class Timer:
	# 该函数在进入上下文管理时执行
    def __enter__(self):
        self.start = time.time()
        return self

	# 该函数在结束上下文管理时执行
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        self.interval = self.end - self.start  # 记录了上下文执行的耗时

    def __str__(self):
        return str(self.interval)

    @property  # 该装饰器使得该方法能像作为属性被调用
    def str(self):
        return self.__str__()

使用时:

with Timer() as elapsed:
    ...  # 要计时的代码
print(f"耗时{elapsed}s")
# 或者使用.str
print(elapsed.str)
更多推荐

DETR纯代码分享(八)position_encoding.py(models)

一、导入一些Python库和模块importmathimporttorchfromtorchimportnnfromutil.miscimportNestedTensor上面的代码段主要是Python代码,用于导入一些Python库和模块,以下是对每行代码的详细解释:importmath:这一行代码导入了Python的

【STM32笔记】HAL库I2C通信配置、读写操作及通用函数定义

【STM32笔记】HAL库I2C通信配置、读写操作及通用函数定义文章目录I2C协议I2C配置I2C操作判断I2C是否响应I2C读写附录:Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时位带操作位带代码位带宏定义总线函数一、位带操作理论及实践

解决Selenium中无法点击元素,Selemium使用JS代码 driver.execute_script点击元素

@FindBy(how=How.XPATH,using="//*[text()='A1.Approved']")privateWebElementApproved;driver.execute_script("arguments[0].click();",Approved)这句话的意思是使用JavaScript在浏览器

【C++】AVL树

个人主页:🍝在肯德基吃麻辣烫我的gitee:C++仓库个人专栏:C++专栏文章目录前言一、什么是AVL树?设计AVL树的原因二、AVL树的性质三、二叉树节点的定义四、AVL树的插入旋转1)右单旋2)左单旋3)左右双旋4)右左双旋AVL树插入完整代码验证一棵树为AVL树AVL树的性能分析总结前言本文章将会模拟实现一棵A

iMazing 2 .17.9最新官方中文版免费下载安装激活

iMazing2.17.9最新版是一款帮助用户管理IOS手机的应用程序,iMazing2最新版能力远超iTunes提供的终极的iOS设备管理器。IMazing与你的iOS设备(iPhone、iPad或iPod)相连,使用起来非常的方便。作为苹果指定的iOS设备同步工具。mazing什么意思iMazing2.17.9是一

springcloud相关面试题

目录springcloud相关面试题SpringCloud几个核心组件服务注册与发现组件——Eureka网关组件——Gateway路由:过滤:服务调用组件——Feign(默认包含Ribbon、Hystrix,基于Ribbon实现负载均衡)Ribbon和Feign调用服务的区别Feign、Ribbon、Hystrix三者

spring的ThreadPoolTaskExecutor装饰器传递调用线程信息给线程池中的线程

概述需求是想在线程池执行任务的时候,在开始前将调用线程的信息传到子线程中,在子线程完成后,再清除传入的数据。下面使用了spring的ThreadPoolTaskExecutor来实现这个需求.ThreadPoolTaskExecutor在jdk中使用的是ThreadPoolExecutor,用于自定义线程池。在spri

FTP和SFT区别记录笔记

项目中,需要使用ftp服务器上传下载文件,之前做过sftp的文件上传下载,以为是一个东西,迅速的把之前的工具类拿过来使用,发现文件为空,特此记录一下二者的区别和工具类。SFTP(SecureFileTransferProtocol)和FTP(FileTransferProtocol)是两种用于文件传输的协议,它们之间有

软考-操作系统

/4操作系统的作用进程进程的概念进程是程序的一次执行过程,没有程序就没有进程进程可有多个线程,线程可共享资源进程的两个基本属性:可拥有资源的独立单位可独立调度和分配资源的基本单位线程可共享:内存地址空间代码数据文件线程不可共享:程序计数器寄存器栈进程的状态进程的调度(PV操作)重重点同步是合作进程的直接制约问题互斥是申

Python-模块

python模块(Module),是一个python文件,以.py结尾,模块可以定义函数,类和变量。模块的导入方法[from模块名]import[模块|类|变量|函数|*][as别名]import模块名importtimetime.sleep(5)from模块import功能fromtimeimportsleepsle

MyBatis面试题(二)

文章目录前言一、MyBatis与Hibernate有哪些不同?二、MyBatis的好处是什么?三、简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系?四、什么是MyBatis的接口绑定,有什么好处?五、接口绑定有几种实现方式,分别是怎么实现的?六、什么情况下用注解绑定,什么情况下用xml绑定?

热文推荐