python黑魔法——上下文管理器

本文介绍了Python中的上下文管理器概念及其应用场景,包括文件读写、数据库查询等资源的分配与释放过程。同时展示了如何自定义上下文管理器并提供了一个计时器的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个熟悉的操作:

下面的操作是我们在文件处理中较为常用的一种方法,使用这种方法读写文件的时候,当with语句下的处理代码块执行完毕后会自动关闭文件读写流,而不需要f.close()

with open('/path/to/file', 'r') as f:
    # <处理代码块开始>
    print(f.read())
    ...
    # <处理代码块结束>
...

这就是上下文管理器给我的第一印象,其实它的作用不止限于文件读写操作

上下文管理器是Python2.5之后才出现的概念。上下文管理器规定了某个对象的使用范围,当进入或者离开了使用范围,都会有相应的一些调用,比如代码块开始时执行一些准备,代码块结束时结束一些操作。它更多的是用于资源的分配和释放上,即在开始时分配资源,结束时释放一些资源。比如在执行数据库查询时要建立连接,查询结束后要释放连接;写文件时要先打开文件,写结束后,要关闭文件等等。还有,就是资源的加锁和解锁,比如在使用多线程时,可能会用到加锁和解锁。
    上下文管理器可以通过使用更可读、更精简的代码实现资源的分配与释放。
实现自己的上下文管理器

要实现一个自定义的上下文管理器,肯定要实现两个方法,一是进入对象范围时的准备工作,二是离开对象范围时的结束工作。下面是一个可以给代码块计时的上下文管理器

import time

class Getime(object):

    def __init__(self, Is_print=False):
        self.Isprint = Is_print

    def __enter__(self):
        self.pre_time = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cur_time = time.time()
        delta_time = self.cur_time - self.pre_time
        if self.Isprint:
            print("the delta time is {0}".format(delta_time) + "s")


# 调用
>>> with Getime(True):
      for i in range(10000000):
          pass

>>> the delta time is 0.4488217830657959s

Python提供了两个类的方法分别实现上述功能:

  • __enter__ 进入对象范围时(一般代码块开始)被调用。配合with语句使用的时候,上下文管理器会自动调用__enter__方法,然后进入运行时上下文环境,如果有as 从句,返回自身或另一个与运行时上下文相关的对象,值赋值给as后跟的变量

  • __exit__ 离开对象范围时(代码块结束)被调用。当with块执行完毕退出with语句块或者with代码块出现异常,则会自动执行__exit__方法,并且会把对于的异常参数传递进来。如果__exit__函数返回True。则with语句代码块不会显示的抛出异常,终止程序,如果返回None或者False,异常会被主动raise,并终止程序。exc_type, exc_val, exc_tb 三个参数指出错误信息
    (更多关于__exit__异常处理的细节问题可以参考http://python.jobbole.com/82289/

因此,一个Python类,只要实现了上述两种方法,就可以说是一个上下文管理器。


梳理一下便是:
  1. 执行 contextor 以获取上下文管理器
  2. 加载上下文管理器的 exit() 方法以备稍后调用
  3. 调用上下文管理器的 enter() 方法
  4. 如果有 as var 从句,则将 enter() 方法的返回值赋给 var
  5. 执行子代码块 with_body
  6. 调用上下文管理器的 exit() 方法,如果 with_body 的退出是由异常引发的,那么该异常的 type、value 和 traceback 会作为参数传给 exit(),否则传三个 None
  7. 如果 with_body 的退出由异常引发,并且 exit() 的返回值等于 False,那么这个异常将被重9新引发一次;如果 exit() 的返回值等于 True,那么这个异常就被无视掉,继续执行后面的代码

所以在代码或函数执行的时候,调用函数时候有一个环境,在不同的环境调用,有时候效果就不一样,这些不同的环境就是上下文。例如数据库连接之后创建了一个数据库交互的上下文,进入这个上下文,就能使用连接进行查询,执行完毕关闭连接退出交互环境。创建连接和释放连接都需要有一个共同的调用环境。不同的上下文,通常见于异步的代码中。


查看当前类是否支持上下文管理器

例如我们查看文件读写类open

>>> print(dir(open))

['__call__',
 '__class__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__name__',
 '__ne__',
 '__new__',
 '__qualname__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__self__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__text_signature__']

可以看到, 列表中存在__enter__函数和__exit__函数,故open支持上下文管理器方法


方案二:
通过python提供的上下文管理工具contextlib可以更优雅的实现上下文管理器,具体参见http://python.jobbole.com/87317/

<think>好的,用户想自学Python编程,询问入门教程。我需要根据提供的引用内容来组织回答,确保符合系统级指令的要求。 首先,用户需要的是入门教程,引用[2]提到了400集的免费教程,适合从零开始学习,应该优先推荐。同时引用[1]中的《Python中文指南》是面向初学者的零基础教程,建议通读,这也是一个重点。 接下来,用户可能需要了解如何配置开发环境。引用[4]提到开发软件和环境配置的教程,这里可以推荐Anaconda和PyCharm,引用[1]里的《PyCharm 中文指南》能帮助用户更好地使用这个IDE。 然后,关于科学计算和数据分析,引用[3]介绍了使用Anaconda和Jupyter Notebook的内容,适合进阶学习,可以作为后续推荐。 还要确保回答结构清晰,分步骤给出建议,比如先基础教程,再开发环境,然后实践项目,最后进阶内容。同时,每个部分末尾自然地添加引用标识。 需要检查是否所有数学公式都用了正确的格式,虽然当前问题可能不涉及数学,但如果有变量或代码,要正确使用代码块。例如Python代码示例需要用```python包裹。 最后生成相关问题,要围绕Python自学路径、开发工具选择、免费资源、科学计算等方面提问,确保问题相关且有参考价值。 现在整理回答结构: 1. 推荐基础教程:引用[2]和[1]中的《Python中文指南》 2. 开发环境配置:引用[4]和[1]中的PyCharm指南 3. 科学计算和数据分析:引用[3] 4. 实践项目:引用[1]的《Python Cookbook》和《Python 黑魔法指南》 5. 注意事项:学习路径、练习、社区支持 然后生成相关问题,覆盖教程选择、开发工具、免费资源、科学计算、实践项目等。 确保引用正确,每个引用后的标识符对应正确的来源。</think>### Python 编程自学入门指南 #### 1. **零基础入门教程推荐** - **《Python中文指南》**:专为初学者设计,内容涵盖基础语法、常用库和实战案例,建议通读并配合练习[^1]。 - **免费视频教程**:B站等平台提供400集免费教程,适合系统性学习(例如变量定义、循环结构等基础概念)[^2]。 #### 2. **开发环境配置** - **Anaconda**:集成Python解释器、Jupyter Notebook和常用科学计算库,适合数据分析场景[^3]。 - **PyCharm**:专业Python IDE,通过《PyCharm 中文指南》可掌握调试、版本控制等高级能[^4]。 ```python # 示例:Python基础语法 print("Hello, World!") ``` #### 3. **科学计算与数据分析** - **《自学Python——编程基础、科学计算及数据分析》**:使用Anaconda环境,结合IPython和Jupyter Notebook讲解数据处理方法[^3]。 #### 4. **实战项目与进阶** - **《Python Cookbook》**:学习高级特性(如装饰器、生成器)和开发技巧。 - **《Python 黑魔法指南》**:积累100+实用技巧(例如列表推导式优化、上下文管理器)[^1]。 #### 5. **注意事项** - **学习路径**:先掌握基础语法 → 熟悉开发工具 → 完成小项目 → 深入特定领域(如Web开发、AI)。 - **练习与社区**:通过LeetCode、Kaggle练习代码,参与GitHub开源项目提升实战能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值