0Pricing
Python Academy · Lekcja

contextlib: @contextmanager

Proszę zwięźle tworzyć menedżery kontekstu za pomocą dekoratora contextlib.

contextlib: @contextmanager to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Dlaczego contextlib?

contextlib.contextmanager pozwala zapisać menedżer kontekstu jako funkcję generatora zamiast klasy, ograniczając ilość kodu pomocniczego.

from contextlib import contextmanager

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

with managed():
    print("inside")

Zwracanie wartości

Wartość zwrócona przez yield jest przypisywana do zmiennej as w instrukcji 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)

Obsługa wyjątków w @contextmanager

Umieść yield wewnątrz try/finally, aby zagwarantować sprzątanie nawet w przypadku wystąpienia wyjątku.

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())

Pomijanie wyjątków

Przechwyć wyjątek wewnątrz generatora, aby go pominąć — działa to tak samo jak zwrócenie True z __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) to gotowy menedżer kontekstu, który pomija określone typy wyjątków.

from contextlib import suppress

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

print("continues")

contextlib.closing

closing(obj) tworzy menedżer kontekstu wywołujący obj.close() przy wychodzeniu z kontekstu. Jest przydatny w przypadku obiektów, które mają metodę close(), ale nie mają __exit__.

from contextlib import closing
from urllib.request import urlopen

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

contextlib.nullcontext

nullcontext to menedżer kontekstu, który nic nie robi. Jest przydatny, gdy menedżer kontekstu jest opcjonalny.

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 pozwala dynamicznie zarządzać zmienną liczbą menedżerów kontekstu.

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]

Ponowne użycie @contextmanager

Menedżer kontekstu oparty na generatorze może zostać użyty tylko raz w ramach jednego wywołania. Aby użyć go ponownie, wywołaj dekorowaną funkcję jeszcze raz.

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

W kodzie asynchronicznym użyj contextlib.asynccontextmanager, aby zapisywać menedżery async with jako generatory.

from contextlib import asynccontextmanager

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

contextlib.redirect_stdout

Tymczasowo przekieruj standardowe wyjście do dowolnego obiektu podobnego do pliku.

import io
from contextlib import redirect_stdout

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

print(buf.getvalue())  # captured

Szybki test

Gdzie w generatorze @contextmanager należy umieścić kod sprzątający, aby zagwarantować jego wykonanie nawet w przypadku wyjątku?

Podsumowanie

@contextmanager przekształca generator w menedżer kontekstu. Użyj try/finally wokół yield, aby bezpiecznie sprzątać zasoby. Moduł contextlib udostępnia również suppress, nullcontext, ExitStack i inne narzędzia.

Często zadawane pytania

Czy lekcja „contextlib: @contextmanager” jest bezpłatna?

Tak — pełny tekst „contextlib: @contextmanager” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „contextlib: @contextmanager”?

Proszę zwięźle tworzyć menedżery kontekstu za pomocą dekoratora contextlib. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „contextlib: @contextmanager”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Instrukcja with — szczegółowe omówienie
  2. Protokół __enter__ i __exit__
  3. contextlib: @contextmanager
  4. Praktyczne wzorce menedżerów kontekstu
← Powrót do Python Academy