0Pricing
Python Academy · บทเรียน

ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์

ใช้งานโพรโทคอล async with และ async for

ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์ เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คำสั่ง async with

ใช้ async with กับตัวจัดการบริบทที่ขั้นตอนการตั้งค่าหรือการเก็บกวาดต้องรอการดำเนินการอินพุต/เอาต์พุต อ็อบเจ็กต์ที่จัดการต้องใช้งาน __aenter__ และ __aexit__ ได้

import asyncio

class AsyncFile:
    async def __aenter__(self):
        print("open")
        return self
    async def __aexit__(self, *args):
        print("close")

async def main():
    async with AsyncFile() as f:
        print("using")

asyncio.run(main())

__aenter__ และ __aexit__

ทั้งสองอย่างเป็นโครูทีน โดยจะรอ __aenter__ เมื่อเข้าสู่บริบท และรอ __aexit__ เมื่อออกจากบริบท แม้จะเกิดข้อยกเว้นขึ้นก็ตาม

import asyncio

class DBSession:
    async def __aenter__(self):
        self.conn = await async_connect()
        return self.conn

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            await self.conn.rollback()
        else:
            await self.conn.commit()
        await self.conn.close()
        return False

@asynccontextmanager

contextlib.asynccontextmanager ช่วยให้คุณเขียนตัวจัดการบริบทแบบอะซิงโครนัสในรูปฟังก์ชันตัวสร้างแบบอะซิงโครนัสได้

from contextlib import asynccontextmanager
import asyncio

@asynccontextmanager
async def managed_resource():
    print("acquire")
    try:
        yield {"status": "ready"}
    finally:
        print("release")

async def main():
    async with managed_resource() as r:
        print(r["status"])

asyncio.run(main())

คำสั่ง async for

async for ใช้วนซ้ำสิ่งที่วนซ้ำได้แบบอะซิงโครนัส ซึ่งเป็นสิ่งที่ใช้งาน __aiter__ และ __anext__ ได้ การวนซ้ำแต่ละครั้งอาจเกี่ยวข้องกับการดำเนินการอินพุต/เอาต์พุต

import asyncio

class AsyncCounter:
    def __init__(self, n): self.n, self.i = n, 0
    def __aiter__(self): return self
    async def __anext__(self):
        if self.i >= self.n: raise StopAsyncIteration
        await asyncio.sleep(0)
        self.i += 1
        return self.i

async def main():
    async for val in AsyncCounter(3):
        print(val)

asyncio.run(main())

ตัวสร้างแบบอะซิงโครนัส

ฟังก์ชัน async def ที่มี yield เป็นตัวสร้างแบบอะซิงโครนัส ให้ใช้ async for เพื่อดึงค่าจากตัวสร้าง

import asyncio

async def ticker(n):
    for i in range(n):
        await asyncio.sleep(1)
        yield i

async def main():
    async for val in ticker(3):
        print(val)   # 0, 1, 2 with 1-s pauses

asyncio.run(main())

aiofiles สำหรับอินพุต/เอาต์พุตไฟล์แบบอะซิงโครนัส

ไลบรารี aiofiles ห่อการดำเนินการกับไฟล์ไว้ในตัวจัดการบริบทและตัววนซ้ำแบบอะซิงโครนัส

# pip install aiofiles
import aiofiles, asyncio

async def main():
    async with aiofiles.open("data.txt", "r") as f:
        async for line in f:
            print(line.strip())

เซสชันไคลเอ็นต์ aiohttp

aiohttp.ClientSession เป็นตัวจัดการบริบทแบบอะซิงโครนัสสำหรับส่งคำขอ HTTP พร้อมกัน

# pip install aiohttp
import aiohttp, asyncio

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

asyncio.run(fetch("https://api.example.com/data"))

ตัวจัดการบริบทแบบอะซิงโครนัสหลายตัว

วางอนุประโยค async with หลายรายการต่อกันในบรรทัดเดียว โดยใช้รูปแบบวงเล็บของ Python 3.10 ขึ้นไป

import asyncio

async def main():
    async with (
        open_db() as db,
        open_cache() as cache,
    ):
        data = await db.fetch("SELECT 1")
        await cache.set("key", data)

AsyncExitStack

contextlib.AsyncExitStack จัดการชุดตัวจัดการบริบทแบบอะซิงโครนัสที่เปลี่ยนแปลงได้

from contextlib import AsyncExitStack
import asyncio

async def main():
    async with AsyncExitStack() as stack:
        conn1 = await stack.enter_async_context(connect("db1"))
        conn2 = await stack.enter_async_context(connect("db2"))
        await process(conn1, conn2)

การทดสอบโค้ดแบบอะซิงโครนัสด้วย pytest-asyncio

pytest-asyncio ช่วยให้คุณเขียนฟังก์ชันทดสอบแบบอะซิงโครนัสด้วยเครื่องหมาย @pytest.mark.asyncio ได้

# pip install pytest-asyncio
import pytest, asyncio

async def fetch(): return 42

@pytest.mark.asyncio
async def test_fetch():
    result = await fetch()
    assert result == 42

สรุปโพรโทคอลตัววนซ้ำแบบอะซิงโครนัส

อ็อบเจ็กต์เป็น สิ่งที่วนซ้ำได้แบบอะซิงโครนัส หากมี __aiter__ และเป็น ตัววนซ้ำแบบอะซิงโครนัส หากมี __anext__ เพิ่มด้วย ตัวสร้างแบบอะซิงโครนัสใช้งานทั้งสองอย่างโดยอัตโนมัติ

import asyncio

async def gen():
    yield 1
    yield 2

async def main():
    g = gen()
    print(await g.__anext__())   # 1
    print(await g.__anext__())   # 2

ตรวจสอบความเข้าใจอย่างรวดเร็ว

อ็อบเจ็กต์ต้องใช้งานเมธอดพิเศษใดบ้างจึงจะใช้กับ async with ได้

สรุปทบทวน

ใช้ async with กับทรัพยากรที่ต้องตั้งค่าหรือเก็บกวาดแบบอะซิงโครนัส ใช้ async for กับสิ่งที่วนซ้ำได้ซึ่งสร้างค่าแบบอะซิงโครนัส ตัวสร้างแบบอะซิงโครนัสช่วยให้สร้างตัววนซ้ำแบบอะซิงโครนัสได้ง่ายขึ้น ไลบรารีอย่าง aiofiles และ aiohttp มีการดำเนินการกับไฟล์และ HTTP แบบอะซิงโครนัสโดยตรง

คำถามที่พบบ่อย

บทเรียน “ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์”

ใช้งานโพรโทคอล async with และ async for คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม

ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครูทีนและลูปเหตุการณ์
  2. await งาน และการรวบรวมงาน
  3. ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์
  4. รูปแบบอะซิงก์ I/O ในระบบจริง
← กลับไปที่ Python Academy