如何用with语句简化你的Python代码

星河几重 2023-06-30 14:56:07 浏览数 (682)
反馈

Python是一门优雅而简洁的编程语言,它提供了许多高级特性,让我们的编程更加方便和高效。其中一个特性就是with语句,它可以让我们在处理一些需要打开和关闭资源的操作时,不用担心忘记关闭资源或者出现异常。在本文中,我将介绍一下with语句的用法和用途,以及它在Python 3.6中新增的一些功能。

with语句的基本用法

with语句的基本语法是这样的:

with expression as variable:
    # do something with variable

expression是一个表达式,它会返回一个上下文管理器(context manager),这是一个实现了__enter____exit__方法的对象。variable是一个变量,它会接收__enter__方法返回的值。当进入with语句时,会调用上下文管理器的__enter__方法,并将返回值赋给variable。当离开with语句时,会调用上下文管理器的__exit__方法,并传入异常信息(如果有的话)。

with语句的作用是让我们可以在执行一些操作之前和之后,自动执行一些清理或者释放资源的操作。比如,当我们要打开一个文件并读取内容时,我们通常要这样写:

f = open('test.txt', 'r')
content = f.read()
f.close()

这样写有两个问题:一是如果读取文件过程中出现异常,可能导致文件没有关闭;二是每次都要写f.close()很麻烦。如果我们用with语句,就可以简化为:

with open('test.txt', 'r') as f:
    content = f.read()

这样写的好处是:一是不管读取文件过程中是否出现异常,都会自动关闭文件;二是代码更加简洁和清晰。这是因为open函数返回的是一个文件对象,它实现了上下文管理器协议,所以可以用在with语句中。

with语句的进阶用法

除了可以用在内置的上下文管理器对象上,我们也可以自己定义上下文管理器类,并用在with语句中。比如,我们想要实现一个计时器类,它可以在进入和离开某个代码块时,打印出执行时间。我们可以这样写:

import time


class Timer:
    def __enter__(self):
        self.start = time.time()
        return self

    
    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.end = time.time()
        print(f'Elapsed time: {self.end - self.start} seconds')

然后我们就可以这样使用:

with Timer() as t:
    # do some heavy computation
    time.sleep(3)

输出:

Elapsed time: 3.000213861465454 seconds

在Python 3.6中,with语句还增加了一些新功能。比如,我们可以在一个with语句中使用多个上下文管理器,只要用逗号分隔即可。比如:

with open('test.txt', 'r') as f1, open('test_copy.txt', 'w') as f2:
    # copy content from f1 to f2

这样就可以同时打开两个文件,并在离开时自动关闭。

另外,我们还可以使用async with语句,在异步编程中使用异步上下文管理器。异步上下文管理器是实现了__aenter____aexit__方法的对象,它们可以在协程中使用,并且支持await语法。比如:

import aiohttp
import asyncio


async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()


async def main():
    html = await fetch('https://www.python.org')
    print(html)


asyncio.run(main())

这样就可以使用aiohttp库,异步地获取网页内容,并在离开时自动关闭会话和响应。

总结

with语句是Python中一个非常有用的特性,它可以让我们在处理一些需要打开和关闭资源的操作时,不用担心忘记关闭资源或者出现异常。它还可以让我们的代码更加简洁和清晰。在Python 3.6中,with语句还增加了一些新功能,让我们可以在一个with语句中使用多个上下文管理器,或者在异步编程中使用异步上下文管理器。如果你还没有使用过with语句,那么我建议你尝试一下,你会发现它的魅力的。

python相关课程推荐:python相关课程

0 人点赞