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():
passasynccontextmanager
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()) # capturedSzybki 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
- Instrukcja with — szczegółowe omówienie
- Protokół __enter__ i __exit__
- contextlib: @contextmanager
- Praktyczne wzorce menedżerów kontekstu