App下載

如何用with語句簡化你的Python代碼

星河幾重 2023-06-30 14:56:07 瀏覽數(shù) (1241)
反饋

Python是一門優(yōu)雅而簡潔的編程語言,它提供了許多高級特性,讓我們的編程更加方便和高效。其中一個(gè)特性就是with語句,它可以讓我們在處理一些需要打開和關(guān)閉資源的操作時(shí),不用擔(dān)心忘記關(guān)閉資源或者出現(xiàn)異常。在本文中,我將介紹一下with語句的用法和用途,以及它在Python 3.6中新增的一些功能。

with語句的基本用法

with語句的基本語法是這樣的:

with expression as variable:
    # do something with variable

expression是一個(gè)表達(dá)式,它會(huì)返回一個(gè)上下文管理器(context manager),這是一個(gè)實(shí)現(xiàn)了__enter____exit__方法的對象。variable是一個(gè)變量,它會(huì)接收__enter__方法返回的值。當(dāng)進(jìn)入with語句時(shí),會(huì)調(diào)用上下文管理器的__enter__方法,并將返回值賦給variable。當(dāng)離開with語句時(shí),會(huì)調(diào)用上下文管理器的__exit__方法,并傳入異常信息(如果有的話)。

with語句的作用是讓我們可以在執(zhí)行一些操作之前和之后,自動(dòng)執(zhí)行一些清理或者釋放資源的操作。比如,當(dāng)我們要打開一個(gè)文件并讀取內(nèi)容時(shí),我們通常要這樣寫:

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

這樣寫有兩個(gè)問題:一是如果讀取文件過程中出現(xiàn)異常,可能導(dǎo)致文件沒有關(guān)閉;二是每次都要寫f.close()很麻煩。如果我們用with語句,就可以簡化為:

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

這樣寫的好處是:一是不管讀取文件過程中是否出現(xiàn)異常,都會(huì)自動(dòng)關(guān)閉文件;二是代碼更加簡潔和清晰。這是因?yàn)閛pen函數(shù)返回的是一個(gè)文件對象,它實(shí)現(xiàn)了上下文管理器協(xié)議,所以可以用在with語句中。

with語句的進(jìn)階用法

除了可以用在內(nèi)置的上下文管理器對象上,我們也可以自己定義上下文管理器類,并用在with語句中。比如,我們想要實(shí)現(xiàn)一個(gè)計(jì)時(shí)器類,它可以在進(jìn)入和離開某個(gè)代碼塊時(shí),打印出執(zhí)行時(shí)間。我們可以這樣寫:

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語句還增加了一些新功能。比如,我們可以在一個(gè)with語句中使用多個(gè)上下文管理器,只要用逗號分隔即可。比如:

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

這樣就可以同時(shí)打開兩個(gè)文件,并在離開時(shí)自動(dòng)關(guān)閉。

另外,我們還可以使用async with語句,在異步編程中使用異步上下文管理器。異步上下文管理器是實(shí)現(xiàn)了__aenter____aexit__方法的對象,它們可以在協(xié)程中使用,并且支持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庫,異步地獲取網(wǎng)頁內(nèi)容,并在離開時(shí)自動(dòng)關(guān)閉會(huì)話和響應(yīng)。

總結(jié)

with語句是Python中一個(gè)非常有用的特性,它可以讓我們在處理一些需要打開和關(guān)閉資源的操作時(shí),不用擔(dān)心忘記關(guān)閉資源或者出現(xiàn)異常。它還可以讓我們的代碼更加簡潔和清晰。在Python 3.6中,with語句還增加了一些新功能,讓我們可以在一個(gè)with語句中使用多個(gè)上下文管理器,或者在異步編程中使用異步上下文管理器。如果你還沒有使用過with語句,那么我建議你嘗試一下,你會(huì)發(fā)現(xiàn)它的魅力的。

python相關(guān)課程推薦:python相關(guān)課程

0 人點(diǎn)贊