Python中的上下文管理器怎么创建

发布时间:2021-11-30 15:39:12 作者:iii
来源:亿速云 阅读:148

这篇文章主要讲解了“Python中的上下文管理器怎么创建”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Python中的上下文管理器怎么创建”吧!

通常我们希望把一些操作放到一个代码块中,在代码块中执行时就可以保持在某种运行状态,而当离开该代码块时就执行另一个操作,结束当前状态;所以,简单来说,上下文管理器的目的就是规定对象的使用范围,如果超出范围就采取“处理”。Python提供了不同的方法来管理执行时间。例如,您可以使用Python的内置timeit模块来管理一小段代码的执行时间。

>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.3018611848820001

但是,timeit.timeit函数仅接受字符串,如果要管理比较复杂的函数时会有局限性。以下示例向您展示如何使用timeit模块运行和管理函数。

def test():
   """Stupid test function"""
   L = [i for i in range(100)]


if __name__ == '__main__':
   import timeit
   print(timeit.timeit("test()", setup="from __main__ import test"))
 

尽管它可以工作,但看起来并不是真正的pythonic。管理执行时间的另一种方法是利用Python的内置cProfile模块,但是并不建议用它,实际上它不是很精确,这只是一种变通方法,可让您了解某些代码段需要执行多长时间。您可以通过以下方式使用它:

>>> python -m cProfile <file_name.py> 

既然上面的两种方法都不是非常Pythonic并且都有缺陷,那么我们如何实现一个比较完美的解决方案呢?

其实很简单:我们只要能拿到程序开始执行和结束执行的时间就可以了,下面介绍具体方法,Python有一个内置模块可供我们使用:time

>>> import time
>>> start = time.time()
>>> # do some stuff
>>> end = time.time()
>>> print(f"Elapsed Time: {end - start}")
 

但是这样写不是很方便。我们可以创建一个上下文管理器。

创建一个上下文管理器

使用Python创建上下文管理器有两种不同方法,我们将研究两种方法来实现此目的:基于类和基于生成器的上下文管理器。

基于类的上下文管理器

要创建基于类的上下文管理器,需要先实现魔法变量__enter____exit__。进入上下文(或代码块)时调用第一个,离开上下文时调用后者。

有了这些准备,我们就可以来创建一个实现这两种方法的Timer类。进入代码块时,我们希望获取当前时间并将其保存到表示开始的变量中。如果我们离开代码块,我们想获取当前时间并从中减去开始时间。结果被打印出来。

为了自定义输出,我们让用户指定一个语句,该语句在经过的时间之前打印。以下要点向您展示了一个即用型的类。

from time import time


class Timer(object):
   def __init__(self, description):
       self.description = description
   def __enter__(self):
       self.start = time()
   def __exit__(self, type, value, traceback):
       self.end = time()
       print(f"{self.description}: {self.end - self.start}")


with Timer("List Comprehension Example"):
   s = [x for x in range(10_000_000)]
 

基于生成器的上下文管理器

基于生成器的方法更加简单。我们可以创建一个包含程序流程的生成器函数(获取开始和结束时间以及打印经过的时间)。@contextmanager装饰器通过使用GeneratorContextManager对象包装生成器,将生成器功能转换为适当的上下文管理器。

from contextlib import contextmanager
from time import time


@contextmanager
def timing(description: str) -> None:
   start = time()
   yield
   ellapsed_time = time() - start

   print(f"{description}: {ellapsed_time}")


with timing("List Comprehension Example"):
   s = [x for x in range(10_000_000)]
如果执行了with后面的代码块,将跳回到yield关键字之后的位置继续执行。

感谢各位的阅读,以上就是“Python中的上下文管理器怎么创建”的内容了,经过本文的学习后,相信大家对Python中的上下文管理器怎么创建这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. Python上下文管理器
  2. python上下文管理器的深度剖析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:exp/imp与expdp/impdp区别是什么

下一篇:C/C++ Qt TreeWidget单层树形组件怎么应用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》