Els gestors de context són una característica poderosa de Python que permet gestionar recursos de manera eficient i segura. S'utilitzen principalment per assegurar-se que els recursos com fitxers, connexions de xarxa, etc., es tanquin correctament després d'haver estat utilitzats, independentment de si s'ha produït una excepció o no.

Continguts

  1. Què és un gestor de context?
  2. Utilitzant with per gestionar recursos
  3. Creació de gestors de context personalitzats
  4. La classe contextlib.ContextDecorator
  5. Exemples pràctics
  6. Exercicis

  1. Què és un gestor de context?

Un gestor de context és un objecte que defineix els mètodes __enter__ i __exit__. Aquests mètodes permeten inicialitzar i netejar recursos respectivament.

  • __enter__(self): S'executa quan el bloc de codi dins del gestor de context comença.
  • __exit__(self, exc_type, exc_value, traceback): S'executa quan el bloc de codi dins del gestor de context acaba, independentment de si s'ha produït una excepció o no.

  1. Utilitzant with per gestionar recursos

La manera més comuna d'utilitzar un gestor de context és amb la declaració with. Aquesta declaració garanteix que els recursos es gestionin correctament.

Exemple bàsic: Obrir i tancar fitxers

with open('example.txt', 'r') as file:
    contents = file.read()
    print(contents)

En aquest exemple:

  • open('example.txt', 'r') retorna un objecte de fitxer.
  • __enter__ obre el fitxer i retorna l'objecte de fitxer.
  • __exit__ tanca el fitxer automàticament quan surt del bloc with.

  1. Creació de gestors de context personalitzats

Podem crear els nostres propis gestors de context definint les classes amb els mètodes __enter__ i __exit__.

Exemple: Gestor de context personalitzat

class MyContextManager:
    def __enter__(self):
        print("Entering the context")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting the context")
        if exc_type:
            print(f"An exception occurred: {exc_value}")
        return True  # Evita que l'excepció es propagui

with MyContextManager() as manager:
    print("Inside the context")
    raise ValueError("Something went wrong")

Sortida:

Entering the context
Inside the context
Exiting the context
An exception occurred: Something went wrong

  1. La classe contextlib.ContextDecorator

El mòdul contextlib proporciona utilitats per treballar amb gestors de context. Una d'aquestes utilitats és ContextDecorator, que permet utilitzar gestors de context com a decoradors.

Exemple: Utilitzant ContextDecorator

from contextlib import ContextDecorator

class MyContextDecorator(ContextDecorator):
    def __enter__(self):
        print("Entering the context")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting the context")
        if exc_type:
            print(f"An exception occurred: {exc_value}")
        return True

@MyContextDecorator()
def my_function():
    print("Inside the function")
    raise ValueError("Something went wrong")

my_function()

Sortida:

Entering the context
Inside the function
Exiting the context
An exception occurred: Something went wrong

  1. Exemples pràctics

Exemple 1: Gestió de connexions de base de dades

class DatabaseConnection:
    def __enter__(self):
        print("Connecting to the database")
        self.connection = "Database connection"
        return self.connection

    def __exit__(self, exc_type, exc_value, traceback):
        print("Closing the database connection")
        self.connection = None

with DatabaseConnection() as conn:
    print(f"Using {conn}")

Sortida:

Connecting to the database
Using Database connection
Closing the database connection

Exemple 2: Temporització de blocs de codi

import time

class Timer:
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.end = time.time()
        self.interval = self.end - self.start
        print(f"Elapsed time: {self.interval:.2f} seconds")

with Timer():
    time.sleep(2)

Sortida:

Elapsed time: 2.00 seconds

  1. Exercicis

Exercici 1: Gestor de context per a fitxers temporals

Crea un gestor de context que creï un fitxer temporal, escrigui algunes dades i després l'esborri quan surti del context.

import os
import tempfile

class TempFile:
    def __enter__(self):
        self.file = tempfile.NamedTemporaryFile(delete=False)
        return self.file

    def __exit__(self, exc_type, exc_value, traceback):
        self.file.close()
        os.remove(self.file.name)

with TempFile() as temp_file:
    temp_file.write(b"Hello, World!")
    temp_file.seek(0)
    print(temp_file.read())

Exercici 2: Gestor de context per a la temporització de funcions

Crea un decorador que mesuri el temps d'execució d'una funció utilitzant ContextDecorator.

from contextlib import ContextDecorator
import time

class Timer(ContextDecorator):
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self.end = time.time()
        self.interval = self.end - self.start
        print(f"Elapsed time: {self.interval:.2f} seconds")

@Timer()
def slow_function():
    time.sleep(3)

slow_function()

Resum

En aquesta secció, hem après què són els gestors de context i com utilitzar-los per gestionar recursos de manera eficient. Hem vist com crear gestors de context personalitzats i com utilitzar ContextDecorator per aplicar gestors de context com a decoradors. També hem treballat amb exemples pràctics i exercicis per reforçar els conceptes apresos.

Curs de Programació en Python

Mòdul 1: Introducció a Python

Mòdul 2: Estructures de Control

Mòdul 3: Funcions i Mòduls

Mòdul 4: Estructures de Dades

Mòdul 5: Programació Orientada a Objectes

Mòdul 6: Gestió de Fitxers

Mòdul 7: Gestió d'Errors i Excepcions

Mòdul 8: Temes Avançats

Mòdul 9: Proves i Depuració

Mòdul 10: Desenvolupament Web amb Python

Mòdul 11: Ciència de Dades amb Python

Mòdul 12: Projecte Final

© Copyright 2024. Tots els drets reservats