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

contextlib: @contextmanager

สร้างตัวจัดการบริบทอย่างกระชับด้วยเดคอเรเตอร์ของ contextlib

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

เหตุใดจึงใช้ contextlib

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

from contextlib import contextmanager

@contextmanager
def managed():
    print("setup")
    yield
    print("teardown")

with managed():
    print("inside")

การส่งคืนค่าด้วย Yield

ค่าที่คุณ yield จะถูกผูกไว้กับตัวแปร as ในคำสั่ง with

from contextlib import contextmanager

@contextmanager
def temp_list():
    lst = []
    yield lst
    print(f"Final list: {lst}")

with temp_list() as lst:
    lst.append(1)
    lst.append(2)

การจัดการข้อยกเว้นใน @contextmanager

ครอบ yield ด้วย try/finally เพื่อรับประกันว่าจะมีการทำความสะอาดแม้เกิดข้อยกเว้น

from contextlib import contextmanager

@contextmanager
def safe_open(path):
    f = open(path)
    try:
        yield f
    finally:
        f.close()

with safe_open("data.txt") as f:
    print(f.read())

การระงับข้อยกเว้น

ดักจับข้อยกเว้นภายในตัวสร้างเพื่อระงับข้อยกเว้นนั้น ซึ่งเทียบเท่ากับการส่งคืน True จาก __exit__

from contextlib import contextmanager

@contextmanager
def ignore_value_errors():
    try:
        yield
    except ValueError:
        pass

with ignore_value_errors():
    raise ValueError("ignored")

contextlib.suppress

contextlib.suppress(*exceptions) คือตัวจัดการบริบทสำเร็จรูปที่ระงับประเภทข้อยกเว้นที่ระบุ

from contextlib import suppress

with suppress(FileNotFoundError):
    open("missing.txt")

print("continues")

contextlib.closing

closing(obj) สร้างตัวจัดการบริบทที่เรียก obj.close() เมื่อออกจากบริบท มีประโยชน์กับอ็อบเจ็กต์ที่มี close() แต่ไม่มี __exit__

from contextlib import closing
from urllib.request import urlopen

with closing(urlopen("https://example.com")) as page:
    content = page.read()

contextlib.nullcontext

nullcontext คือตัวจัดการบริบทที่ไม่ทำงานใด ๆ มีประโยชน์เมื่อตัวจัดการบริบทเป็นตัวเลือก

from contextlib import nullcontext

def process(data, lock=None):
    cm = lock if lock is not None else nullcontext()
    with cm:
        return [x*2 for x in data]

contextlib.ExitStack

ExitStack ช่วยให้คุณจัดการตัวจัดการบริบทจำนวนที่เปลี่ยนแปลงได้แบบไดนามิก

from contextlib import ExitStack

files = ["a.txt", "b.txt", "c.txt"]
with ExitStack() as stack:
    handles = [stack.enter_context(open(f)) for f in files]
    data = [h.read() for h in handles]

การนำ @contextmanager กลับมาใช้ใหม่

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

from contextlib import contextmanager

@contextmanager
def counter():
    count = 0
    yield lambda: count.__add__  # each call is independent
    print("done")

with counter():
    pass
with counter():
    pass

asynccontextmanager

สำหรับโค้ดแบบอะซิงโครนัส ให้ใช้ contextlib.asynccontextmanager เพื่อเขียนตัวจัดการ async with ในรูปแบบตัวสร้าง

from contextlib import asynccontextmanager

@asynccontextmanager
async def async_session():
    session = await create_session()
    try:
        yield session
    finally:
        await session.close()

contextlib.redirect_stdout

เปลี่ยนเส้นทางเอาต์พุตมาตรฐานไปยังอ็อบเจ็กต์ที่มีลักษณะเหมือนไฟล์ใด ๆ เป็นการชั่วคราว

import io
from contextlib import redirect_stdout

buf = io.StringIO()
with redirect_stdout(buf):
    print("captured")

print(buf.getvalue())  # captured

ตรวจสอบอย่างรวดเร็ว

ในตัวสร้างของ @contextmanager ควรวางโค้ดทำความสะอาดไว้ที่ใดเพื่อรับประกันว่าจะทำงานแม้เกิดข้อยกเว้น

สรุป

@contextmanager เปลี่ยนตัวสร้างให้เป็นตัวจัดการบริบท ใช้ try/finally ครอบ yield เพื่อทำความสะอาดอย่างปลอดภัย โมดูล contextlib ยังมี suppress, nullcontext, ExitStack และอื่น ๆ ให้ใช้งาน

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

บทเรียน “contextlib: @contextmanager” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “contextlib: @contextmanager”

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

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

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

บทเรียน “contextlib: @contextmanager” ใช้เวลานานแค่ไหน

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

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

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

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

  1. เจาะลึกคำสั่ง with
  2. โพรโทคอล __enter__ และ __exit__
  3. contextlib: @contextmanager
  4. รูปแบบการใช้ตัวจัดการบริบทในทางปฏิบัติ
← กลับไปที่ Python Academy