python with使用详解

 更新时间:2025年11月03日 10:07:06   作者:令狐掌门  
with语句是Python中一种用于资源管理的语法结构,主要用于确保资源(如文件、锁、数据库连接等)在使用后被正确释放,即使发生异常也不会遗漏清理操作,本文给大家介绍python with使用,感兴趣的朋友跟随小编一起看看吧

1. Pythonwith语句的原理

with语句是Python中一种用于资源管理的语法结构,主要用于确保资源(如文件、锁、数据库连接等)在使用后被正确释放,即使发生异常也不会遗漏清理操作。它本质上是基于上下文管理器(Context Manager)协议实现的。

核心原理:

  • with语句会调用上下文管理器的两个特殊方法:
    • __enter__():进入with块时调用,返回一个值(通常是资源对象本身),这个值可以被as关键字赋值给变量。
    • __exit__(exc_type, exc_value, traceback):退出with块时调用,无论是否发生异常都会执行。它接收三个参数(异常类型、异常值、回溯信息),如果返回True,则抑制异常(不抛出);否则,异常会继续传播。
  • with语句相当于简化版的try...finally结构:
    • 进入时执行__enter__()(类似于try前的准备)。
    • 执行with块内的代码。
    • 退出时执行__exit__()(类似于finally块中的清理)。
  • 好处:自动处理资源释放,避免手动编写try...except...finally块,减少错误(如忘记关闭文件)。

如果没有异常,__exit__的参数均为None。这使得with特别适合“获取-使用-释放”模式的操作。

2.with语句的用法

with语句的基本语法:

with 上下文管理器 [as 变量]:
    # 在这里使用资源
    # 块结束时自动清理

示例1:文件操作(最常见用法)

with open('example.txt', 'r') as file:
    content = file.read()
    print(content)
# 文件在with块结束后自动关闭,无需手动调用file.close()
  • 原理:open()返回的文件对象实现了上下文管理器协议,__enter__返回文件对象本身,__exit__关闭文件。

示例2:多上下文管理器

Python支持嵌套或并列使用多个with

with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
    content = infile.read()
    outfile.write(content.upper())

示例3:处理异常

try:
    with open('nonexistent.txt', 'r') as file:
        print(file.read())
except FileNotFoundError:
    print("文件不存在")
  • 如果with块内抛出异常,__exit__仍会执行清理,然后异常传播到外层。

with常用于:

  • 文件I/O(open())。
  • 线程锁(threading.Lock())。
  • 数据库连接(许多库如SQLAlchemy支持)。
  • 临时更改(如os.chdir()的上下文版本)。

3. 如何定义一个对象使其支持with语句

要让自定义对象支持with,需要实现上下文管理器协议。有两种主要方式:类实现生成器实现(使用contextlib模块)。

方式1:通过类实现__enter__和__exit__

定义一个类,添加__enter____exit__方法。

class MyResource:
    def __init__(self, name):
        self.name = name
        print(f"初始化资源: {name}")
    def __enter__(self):
        print(f"进入with块: 获取资源 {self.name}")
        return self  # 返回对象本身,供as使用
    def __exit__(self, exc_type, exc_value, traceback):
        print(f"退出with块: 释放资源 {self.name}")
        if exc_type is not None:
            print(f"发生异常: {exc_type}")
            return False  # 不抑制异常,让它传播
        return True  # 正常退出
# 用法
with MyResource("数据库连接") as res:
    print(f"使用资源: {res.name}")
    # raise ValueError("模拟异常")  # 可以测试异常处理

输出示例(无异常):

初始化资源: 数据库连接
进入with块: 获取资源 数据库连接
使用资源: 数据库连接
退出with块: 释放资源 数据库连接

方式2:使用contextlib模块的@contextmanager装饰器(基于生成器)

这是一种更简洁的方式,适合临时上下文,不需要定义整个类。

from contextlib import contextmanager
@contextmanager
def my_resource(name):
    print(f"进入with块: 获取资源 {name}")
    yield name.upper()  # yield前的代码相当于__enter__,yield的值供as使用
    print(f"退出with块: 释放资源 {name}")  # yield后的代码相当于__exit__
# 用法
with my_resource("文件锁") as res:
    print(f"使用资源: {res}")

输出:

进入with块: 获取资源 文件锁
使用资源: 文件锁
退出with块: 释放资源 文件锁

  • 处理异常:在生成器中,可以用try...except包裹yield,以自定义异常行为。

注意事项:

  • __enter__返回的值可以是任何对象,不一定是self(例如,返回一个计算结果)。
  • __exit__中,如果要抑制异常,返回True;否则返回FalseNone
  • 如果对象不支持上下文管理器,使用with会抛出AttributeError(缺少__enter____exit__)。
  • Python 3.10+ 支持异步上下文管理器(__aenter____aexit__),用于async with

通过这些方式,可以为任何需要资源管理的场景自定义with支持。

到此这篇关于python with使用介绍的文章就介绍到这了,更多相关python with使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python获取当前函数名称方法实例分享

    Python获取当前函数名称方法实例分享

    这篇文章主要介绍了Python获取当前函数名称方法实例分享,具有一定借鉴价值
    2018-01-01
  • python利用标准库如何获取本地IP示例详解

    python利用标准库如何获取本地IP示例详解

    这篇文章主要给大家介绍了关于python利用标准库如何获取本地IP的相关资料,文中先对python的标准库进行了简单的介绍,而后给大家详细介绍了关于python用标准库获取本地IP的实现方法,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • Python中uuid模块的应用实例详解

    Python中uuid模块的应用实例详解

    这篇文章主要介绍了Python中uuid模块应用的相关资料,该模块提供了多种方法生成UUID,包括uuid1()、uuid3()、uuid4()和uuid5(),并解释了UUID的格式,UUID在数据库、分布式系统和网络协议中广泛应用,是处理唯一标识符的有力工具,需要的朋友可以参考下
    2024-11-11
  • Django获取请求参数的常用方式

    Django获取请求参数的常用方式

    这篇文章主要为大家详细介绍了在Django中获取请求参数的几种常用方式,文中展示里具体的实现示例代码,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-05-05
  • 用Python做一个久坐提醒小助手的示例代码

    用Python做一个久坐提醒小助手的示例代码

    这篇文章主要介绍了用Python做一个久坐提醒小助手的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • python 输入字符串生成所有有效的IP地址(LeetCode 93号题)

    python 输入字符串生成所有有效的IP地址(LeetCode 93号题)

    这篇文章主要介绍了python 生成所有有效的IP地址的方法,帮助大家解答题目,学习python,感兴趣的朋友可以了解下
    2020-10-10
  • python调用腾讯云实名认证接口辨别身份证真假

    python调用腾讯云实名认证接口辨别身份证真假

    这篇文章主要为大家介绍了python辨别身份真假之腾讯云身份证实名认证接口,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Python实例详解递归算法

    Python实例详解递归算法

    递归(英语:Recursion),又译为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。递归一词还较常用于描述以自相似方法重复事物的过程。本文将详细为大家介绍Python中的递归算法,需要的可以参考一下
    2022-03-03
  • 利用Python创建第一个Django框架程序

    利用Python创建第一个Django框架程序

    这篇文章主要介绍了利用Python创建第一个Django框架程序,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下
    2022-06-06
  • python对一个数向上取整的实例方法

    python对一个数向上取整的实例方法

    在本篇文章中小编给大家整理了关于python对一个数向上取整的实例方法,需要的朋友们可以跟着学习下。
    2020-06-06

最新评论