Jak korzystać z menedżerów kontekstu w Pythonie (z instrukcją)

Dowiedz się, jak menedżerowie kontekstu działają w Pythonie. Opanuj instrukcję with, zarządzaj zasobami systemowymi i pisz niestandardowe menedżery kontekstu.

Wypróbuj to rozwiązanie w Edytorze

Przegląd

Prawidłowe zarządzanie zasobami zewnętrznymi — takimi jak zamykanie uchwytów plików, rozłączanie połączeń z bazami danych i zwalnianie blokad wątków — jest niezbędne do tworzenia niezawodnego oprogramowania gotowego do produkcji. Nieuwolnienie zasobów może skutkować wyciekami pamięci, błędami blokowania plików i zawieszaniem się aplikacji.

Instrukcja `with` Pythona upraszcza czyszczenie zasobów poprzez utworzenie menedżera kontekstu. Menedżer kontekstu gwarantuje, że akcje czyszczące zostaną automatycznie wykonane, gdy kontrola opuści blok, nawet jeśli kod zgłosi wyjątek lub zakończy działanie wcześniej. Eliminuje to potrzebę stosowania pełnych, powtarzalnych bloków typu „spróbuj w końcu”.

Chociaż menedżery kontekstów są najczęściej kojarzone z wbudowanymi operacjami, takimi jak „open()”, możesz łatwo zaprojektować własne, niestandardowe menedżery kontekstu. Można je zbudować, tworząc klasę implementującą magiczne metody `__enter__` i `__exit__` lub pisząc funkcję generatora ozdobioną dekoratorem `contextlib.contextmanager`.

Dane wyjściowe kodu i wykonania

Ten skrypt demonstruje pisanie niestandardowych menedżerów kontekstu w Pythonie przy użyciu implementacji klas i dekoratorów kontekstowych.

context_managers.py
Spróbuj w Edytorze
from contextlib import contextmanager

# Method 1: Class-based context manager
class CustomResource:
    def __enter__(self):
        print("[Resource] Opening connection...")
        return self

    def do_work(self):
        print("[Resource] Performing action...")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("[Resource] Closing connection safely.")
        return False

print("--- Class Context Manager ---")
with CustomResource() as resource:
    resource.do_work()

# Method 2: Generator-based context manager (contextlib)
@contextmanager
def simple_timer():
    print("\n[Timer] Started...")
    try:
        yield
    finally:
        print("[Timer] Finished!")

print("\n--- Decorator Context Manager ---")
with simple_timer():
    print("Performing tasks inside context...")
Wyjście terminala
--- Class Context Manager ---
[Resource] Opening connection...
[Resource] Performing action...
[Resource] Closing connection safely.

--- Decorator Context Manager ---

[Timer] Started...
Performing tasks inside context...
[Timer] Finished!

Wdrażanie krok po kroku

  • Użyj instrukcji with podczas otwierania plików, baz danych lub blokad, aby zagwarantować bezpieczeństwo zasobów.
  • Zdefiniuj niestandardowe menedżery kontekstu za pomocą klas z magicznymi metodami __enter__ i __exit__.
  • Użyj dekoratora @contextlib.contextmanager w funkcji generatora jako prostszej, opartej na funkcjach alternatywy.
  • Umieść akcje zamykania zasobów w bloku czyszczącym, aby mieć pewność, że zostaną uruchomione nawet w przypadku wystąpienia błędów.

Często zadawane pytania

Jakie parametry otrzymuje metoda __exit__?

Metoda __exit__ otrzymuje trzy argumenty reprezentujące szczegóły wyjątku, jeśli taki został zgłoszony: exc_type (typ wyjątku), exc_val (wartość wyjątku) i exc_tb (śledzenie). Jeśli nie wystąpił żaden błąd, wszystkie trzy są przekazywane jako Brak.

Czy menedżer kontekstu może ukryć wyjątki?

Tak. Jeśli metoda __exit__ zwróci wartość prawdziwą (np. True), Python pomija wyjątek i wykonywanie jest kontynuowane po bloku with. Jeśli zwróci False, wyjątek zostanie zgłoszony normalnie.

Powiązane tematy

Polecane zasoby Pythona

Poszerzaj swoją wiedzę dzięki powiązanym interaktywnym samouczkom, ściągawkom i porównaniom kodów.