Potresti già conoscere l'istruzione with, un modo conciso per gestire le risorse in Python. Ma ti sei mai chiesto come funzioni dietro le quinte? Ebbene, la potenza della keyword with deriva dai context manager.
I context manager sono un pattern fondamentale in Python che offre un approccio strutturato alla gestione delle risorse. Garantisce che le risorse vengano acquisite, usate correttamente e infine rilasciate o ripulite, anche in presenza di errori o eccezioni.
Questo diventa particolarmente importante quando si lavora con risorse come file, connessioni di rete o handle di database. Usando i context manager, possiamo scrivere codice più pulito e affidabile, liberandoci dalla preoccupazione di dimenticare di chiudere un file o rilasciare un lock.
In questo tutorial, andremo oltre i context manager predefiniti di Python e impareremo a scrivere i nostri.
Capire i context manager in Python
Dietro le quinte, i context manager sono oggetti che definiscono due metodi speciali: __enter__ e __exit__. Il metodo __enter__ viene chiamato quando entri nel blocco with, e il suo valore di ritorno viene assegnato a una variabile all'interno di quel blocco. Il metodo __exit__, invece, viene chiamato quando si esce dal blocco with, indipendentemente dal fatto che termini normalmente o con un'eccezione.
Questa struttura garantisce una corretta gestione delle risorse. Vediamo alcuni context manager integrati in Python per capirlo meglio:
Prendiamo il classico esempio dell'apertura di un file:
withopen('file.txt','r')asfile:
data =file.read()Offerto da
Qui, open('file.txt', 'r') funge da context manager. Quando entri nel blocco with, il metodo enter dell'oggetto file viene chiamato, aprendo il file e assegnandolo alla variabile file. Puoi quindi usare file.read() per accedere al contenuto del file.
Successivamente, il metodo __exit__ dell'oggetto file è garantito alla chiusura del blocco with, anche se si verifica un'eccezione. Questo metodo si occupa di chiudere il file, assicurandoti di non lasciare handle di file aperti in giro.
2. Lock dei thread
Oltre ai file, i context manager possono essere usati anche per la sincronizzazione dei thread con threading.Lock():
import threading
lock = threading.Lock()with lock:# Critical sectionprint("This code is executed under lock protection.")Offerto da
Qui, lock è un oggetto threading.Lock, un altro context manager. Quando entri nel blocco with, il metodo __enter__ acquisisce il lock, assicurando che solo un thread alla volta possa eseguire la sezione critica. Infine, il metodo __exit__ rilascia il lock all'uscita dal blocco with, permettendo agli altri thread di continuare.
3. Connessioni al database
Allo stesso modo, i context manager possono gestire le connessioni ai database:
import sqlite3
with sqlite3.connect('database.db')as connection:
cursor = connection.cursor()
cursor.execute("SELECT * FROM table")
rows = cursor.fetchall()Offerto da
La chiamata sqlite3.connect('database.db') è un context manager. Entrando nel blocco with viene stabilita una connessione al database, assegnata a connection. Puoi quindi usare un cursor per interagire con il database. Il metodo __exit__ garantisce la chiusura della connessione all'uscita dal blocco with, prevenendo leak di risorse.
4. Socket di rete
I context manager possono gestire anche la comunicazione di rete:
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM)as s:
s.connect(('localhost',8080))
s.sendall(b'Hello, world')
data = s.recv(1024)Offerto da
Qui, socket.socket(socket.AF_INET, socket.SOCK_STREAM) crea un oggetto socket che funge da context manager. Il metodo __enter__ crea il socket e, all'interno del blocco with, puoi connetterti, inviare e ricevere dati. Il metodo __exit__ assicura che il socket venga chiuso correttamente al termine.
5. Scansione di directory
Questa volta, os.scandir('.') fornisce un modo per iterare sulle voci di una directory:
with os.scandir('.')as entries:for entry in entries:print(entry.name)Offerto da
os.scandir('.') funge da context manager qui. Il metodo __enter__ apre una scansione della directory, e puoi iterare sulle voci all'interno del blocco with. Il metodo __exit__ ripulisce la scansione della directory all'uscita.
Come vedi, l'istruzione with, grazie ai context manager, semplifica la gestione delle risorse occupandosi automaticamente di allocazione e deallocazione.
Scrivere context manager personalizzati in Python
Ora vediamo finalmente come scrivere i tuoi manager personalizzati per avere un controllo fine sulla gestione delle risorse.
Ci sono due approcci principali per scrivere context manager personalizzati: basato su classi e basato su funzioni.
Approccio basato su classi
L'approccio basato su classi è il metodo più strutturato e flessibile per scrivere context manager. Qui, definisci una classe che implementa i metodi speciali __enter__ e __exit__.
Vediamo un esempio di classe Timer che misura il tempo di esecuzione:
import time
classTimer:def__enter__(self):
self.start_time = time.time()return self
def__exit__(self, exc_type, exc_value, traceback):
self.end_time = time.time()
elapsed_time = self.end_time - self.start_time
print(f"Elapsed time: {elapsed_time} seconds")# Example usageif __name__ =="__main__":with Timer()as timer:# Code block to measure the execution time
time.sleep(2)# Simulate some time-consuming operation
Elapsed time:2.002082347869873 seconds
Offerto da
Qui, la classe Timer definisce il metodo __enter__ per catturare l'orario di inizio quando entri nel blocco with. Restituisce self per consentire l'accesso all'oggetto all'interno del blocco. Il metodo __exit__ calcola il tempo trascorso all'uscita dal blocco with e lo stampa.
Approccio basato su funzioni
Se preferisci un approccio più conciso, magari a scapito della flessibilità, l'approccio basato su funzioni può essere una buona opzione. Qui usi il decorator contextmanager del modulo contextlib per convertire qualsiasi funzione in un context manager.
Vediamo come funziona:
import time
from contextlib import contextmanager
@contextmanagerdeftimer():
start_time = time.time()yield
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Elapsed time: {elapsed_time} seconds")# Example usageif __name__ =="__main__":with timer():
time.sleep(2)
Elapsed time:2.0020740032196045 seconds
Offerto da
Il decorator @contextmanager trasforma la funzione timer in un context manager. All'interno della funzione, viene catturato start_time, e l'istruzione yield mette in pausa l'esecuzione, permettendo al codice nel blocco with di essere eseguito.
Infine, la funzionalità di __exit__ è ottenuta catturando il tempo di fine e stampando il tempo trascorso.
In sostanza, scrivi la logica di __enter__ prima della keyword yield, mentre la logica di __exit__ viene dopo. Entrambi gli approcci raggiungono lo stesso risultato, ma la scelta dipende dalla tua preferenza per struttura e leggibilità.
Esempi pratici di context manager
Ora che sai come scrivere context manager personalizzati in Python, vediamo alcuni esempi pratici in cui possono essere estremamente utili.
Gestione delle operazioni su file
Le operazioni su file sono un compito comune in molte applicazioni. Che si tratti di leggere o scrivere file, una gestione corretta garantisce integrità dei dati ed efficienza nell'uso delle risorse. Consideriamo uno scenario in cui vogliamo scrivere del testo su un file usando un context manager personalizzato.
In questo esempio, definiamo una classe FileManager per imitare la funzione open di Python che gestisce le operazioni sui file. Vediamo cosa fa ciascun metodo:
__init__(self, filename, mode): Questo metodo è il costruttore della classe. Inizializza l'oggetto FileManager con il nome file e la modalità forniti, che specificano il file da aprire e la modalità in cui aprirlo (ad esempio, lettura, scrittura, append).
__enter__(self): Questo metodo viene chiamato all'ingresso del blocco with, come sempre. Apre il file specificato da filename nella modalità specificata da mode. L'oggetto file aperto viene assegnato a self.file e restituito per essere usato all'interno del blocco with.
__exit__(self, exc_type, exc_value, traceback): Questo metodo viene chiamato all'uscita dal blocco with, indipendentemente dal fatto che si sia verificata un'eccezione all'interno del blocco. Garantisce che il file venga chiuso correttamente chiamando self.file.close() se self.file non è None. Questo previene leak di risorse e assicura una corretta pulizia.
Se ispezioni il contenuto di example.txt dopo aver eseguito il codice sopra, dovresti vedere il testo scritto:
Ovviamente, il vantaggio della classe FileManager è che puoi implementare qualsiasi logica personalizzata per lavorare con i file. Per esempio, puoi modificarla in modo che la classe tenga traccia, in un file di log, di quali file vengono aperti o chiusi.
Il modulo datetime è importato per lavorare con i timestamp.
È stato aggiunto il metodo log_action per registrare le azioni sui file.
È stato aggiunto il parametro log_filename per specificare il nome del file di log. Il valore predefinito è 'file_log.txt'.
Il nome del file e l'azione (aperto o chiuso) vengono aggiunti al file di log usando il metodo log_action all'interno dei metodi __enter__ e __exit__.
All'interno del metodo log_action, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") viene usato per ottenere il timestamp corrente nel formato "YYYY-MM-DD HH:MM:SS".
Il timestamp viene poi incluso nel log insieme al nome del file e all'azione.
Ora, se stampiamo il contenuto di file_log.txt, dovremmo vedere i log:
Anche questo imita la funzione sqlite3.connect, ma può essere ulteriormente migliorato aggiungendo logica personalizzata di gestione del database. Verifichiamo se il manager funziona con alcune funzioni di esempio:
# Example usagedefcreate_table():with DatabaseConnection("example.db")as connection:
cursor = connection.cursor()
cursor.execute("""CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
username TEXT,
email TEXT)""")definsert_data(username, email):with DatabaseConnection("example.db")as connection:
cursor = connection.cursor()
cursor.execute("INSERT INTO users (username, email) VALUES (?, ?)",(username, email))
connection.commit()deffetch_data():with DatabaseConnection("example.db")as connection:
cursor = connection.cursor()
cursor.execute("SELECT * FROM users")return cursor.fetchall()if __name__ =="__main__":
create_table()
insert_data("john_doe","[email protected]")
insert_data("jane_doe","[email protected]")
users = fetch_data()print("Users in the database:")for user in users:print(user)
Users in the database:(1,'john_doe','[email protected]')(2,'jane_doe','[email protected]')(3,'john_doe','[email protected]')(4,'jane_doe','[email protected]')Offerto da
Possiamo scrivere codice molto più manutenibile suddividendo le operazioni sul database in funzioni e usando il manager personalizzato che abbiamo appena creato.
Argomenti avanzati relativi ai context manager in Python
In questa sezione tratteremo argomenti avanzati relativi ai context manager in Python. Questi includono la gestione degli errori e l'annidamento dei context manager.
Gestione degli errori
La gestione degli errori è un aspetto essenziale della programmazione, e i context manager in Python offrono un modo pratico per gestire gli errori nelle operazioni di gestione delle risorse.
Nell'esempio della classe FileManager, la gestione degli errori può essere implementata all'interno del metodo __exit__ per garantire una corretta pulizia anche se si verifica un'eccezione. Per esempio, se si verifica un errore durante la scrittura del file (mentre siamo dentro il blocco with), vogliamo comunque assicurarci che il file venga chiuso per evitare leak di risorse. Possiamo modificare il metodo __exit__ come segue:
Qui, chiudiamo prima il file usando self.file.close() per garantire una corretta pulizia. Poi, verifichiamo se si è verificata un'eccezione (exc_type is not None). In tal caso, stampiamo un messaggio di errore per dare un riscontro su cosa sia andato storto.
Qui:
exc_type è la classe dell'eccezione, come AttributeError e IndexError.
exc_value è l'istanza dell'eccezione con il messaggio.
traceback è il traceback completo dell'errore.
Eseguiamo la classe FileManager con un codice volutamente errato:
with FileManager("example.txt","r")asfile:# Simulate a sample error
content =file.read()print(content[150])
An error occurred: string index out of rangeOfferto da
Quindi, per implementare logiche personalizzate quando gestisci eccezioni nei tuoi manager, ecco un flusso di lavoro di esempio che puoi seguire:
def__exit__(self, exc_type, exc_value, traceback):# Perform cleanup...# Handle the exceptionifisinstance(exc_value, AttributeError):# Handle AttributeError hereprint(f"Exception message: {exc_value}")# Handle another exceptionelifisinstance(exc_value, AnotherError):...Offerto da
Annidare i context manager
Annidare i context manager ti consente di gestire più risorse contemporaneamente, ciascuna con il proprio context manager, all'interno di una singola istruzione with. Questo è particolarmente utile quando si affrontano operazioni complesse che coinvolgono più risorse. Vediamo come possiamo annidare i context manager nei nostri esempi.
Considera uno scenario in cui vogliamo aprire un file ed eseguire operazioni sul database nello stesso contesto. Magari, vogliamo inserire il contenuto di un file CSV come righe in un database. Possiamo ottenere questo risultato annidando i context manager FileManager e DatabaseConnection nella stessa istruzione with:
if __name__ =="__main__":with FileManager("example.txt","w")asfile, DatabaseConnection("example.db")as connection:...Offerto da
In questo esempio, i context manager FileManager e DatabaseConnection sono annidati nella stessa istruzione with. Questo ci permette di aprire il file e stabilire una connessione al database contemporaneamente. Le successive operazioni di scrittura su file e sul database vengono eseguite all'interno di questo contesto combinato.
Una cosa da tenere a mente è la leggibilità del codice. Ti consiglierei che il numero di contesti simultanei non superi due.
Conclusione
I context manager in Python offrono un approccio strutturato alla gestione delle risorse all'interno di un'istruzione with, garantendo una corretta allocazione e deallocazione delle risorse.
In tutto il tutorial, abbiamo imparato le basi dei context manager, visto esempi pratici e discusso argomenti avanzati come la gestione degli errori e l'annidamento. Padroneggiando la scrittura di context manager personalizzati, potrai scrivere codice più pulito e affidabile, migliorare la gestione degli errori e gestire le risorse in modo efficiente.
L'argomento della scrittura di context manager personalizzati rientra nella categoria "Python avanzato". Ecco alcune risorse correlate per migliorare ulteriormente le tue competenze:
Sono un creator di contenuti sulla data science con oltre 2 anni di esperienza e uno dei più seguiti su Medium. Mi piace scrivere articoli dettagliati su AI e ML con un pizzico di sarcasmo, perché bisogna pur fare qualcosa per renderli un po’ meno noiosi. Ho pubblicato oltre 130 articoli e un corso su DataCamp, con un altro in arrivo. I miei contenuti sono stati visti da oltre 5 milioni di persone, 20.000 delle quali sono diventate follower sia su Medium che su LinkedIn.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Migliora le tue abilità di programmazione. Impara a ottimizzare il codice, a scrivere funzioni e test e a utilizzare le migliori tecniche di ingegneria del software.
Motivazione
Potresti già conoscere l'istruzione
with, un modo conciso per gestire le risorse in Python. Ma ti sei mai chiesto come funzioni dietro le quinte? Ebbene, la potenza della keywordwithderiva dai context manager.I context manager sono un pattern fondamentale in Python che offre un approccio strutturato alla gestione delle risorse. Garantisce che le risorse vengano acquisite, usate correttamente e infine rilasciate o ripulite, anche in presenza di errori o eccezioni.
Questo diventa particolarmente importante quando si lavora con risorse come file, connessioni di rete o handle di database. Usando i context manager, possiamo scrivere codice più pulito e affidabile, liberandoci dalla preoccupazione di dimenticare di chiudere un file o rilasciare un lock.
In questo tutorial, andremo oltre i context manager predefiniti di Python e impareremo a scrivere i nostri.
Capire i context manager in Python
Dietro le quinte, i context manager sono oggetti che definiscono due metodi speciali:
__enter__e__exit__. Il metodo__enter__viene chiamato quando entri nel blocco with, e il suo valore di ritorno viene assegnato a una variabile all'interno di quel blocco. Il metodo__exit__, invece, viene chiamato quando si esce dal bloccowith, indipendentemente dal fatto che termini normalmente o con un'eccezione.Questa struttura garantisce una corretta gestione delle risorse. Vediamo alcuni context manager integrati in Python per capirlo meglio:
1. Gestione dei file
Prendiamo il classico esempio dell'apertura di un file:
Qui,
open('file.txt', 'r')funge da context manager. Quando entri nel bloccowith, il metodo enter dell'oggetto file viene chiamato, aprendo il file e assegnandolo alla variabile file. Puoi quindi usarefile.read()per accedere al contenuto del file.Successivamente, il metodo
__exit__dell'oggetto file è garantito alla chiusura del bloccowith, anche se si verifica un'eccezione. Questo metodo si occupa di chiudere il file, assicurandoti di non lasciare handle di file aperti in giro.2. Lock dei thread
Oltre ai file, i context manager possono essere usati anche per la sincronizzazione dei thread con
threading.Lock():Qui,
lockè un oggettothreading.Lock, un altro context manager. Quando entri nel bloccowith, il metodo__enter__acquisisce il lock, assicurando che solo un thread alla volta possa eseguire la sezione critica. Infine, il metodo__exit__rilascia il lock all'uscita dal bloccowith, permettendo agli altri thread di continuare.3. Connessioni al database
Allo stesso modo, i context manager possono gestire le connessioni ai database:
La chiamata
sqlite3.connect('database.db')è un context manager. Entrando nel bloccowithviene stabilita una connessione al database, assegnata aconnection. Puoi quindi usare uncursorper interagire con il database. Il metodo__exit__garantisce la chiusura della connessione all'uscita dal bloccowith, prevenendo leak di risorse.4. Socket di rete
I context manager possono gestire anche la comunicazione di rete:
Qui,
socket.socket(socket.AF_INET, socket.SOCK_STREAM)crea un oggetto socket che funge da context manager. Il metodo__enter__crea il socket e, all'interno del bloccowith, puoi connetterti, inviare e ricevere dati. Il metodo__exit__assicura che il socket venga chiuso correttamente al termine.5. Scansione di directory
Questa volta,
os.scandir('.')fornisce un modo per iterare sulle voci di una directory:os.scandir('.')funge da context manager qui. Il metodo__enter__apre una scansione della directory, e puoi iterare sulle voci all'interno del bloccowith. Il metodo__exit__ripulisce la scansione della directory all'uscita.Come vedi, l'istruzione
with, grazie ai context manager, semplifica la gestione delle risorse occupandosi automaticamente di allocazione e deallocazione.Scrivere context manager personalizzati in Python
Ora vediamo finalmente come scrivere i tuoi manager personalizzati per avere un controllo fine sulla gestione delle risorse.
Ci sono due approcci principali per scrivere context manager personalizzati: basato su classi e basato su funzioni.
Approccio basato su classi
L'approccio basato su classi è il metodo più strutturato e flessibile per scrivere context manager. Qui, definisci una classe che implementa i metodi speciali
__enter__e__exit__.Vediamo un esempio di classe
Timerche misura il tempo di esecuzione:Qui, la classe
Timerdefinisce il metodo__enter__per catturare l'orario di inizio quando entri nel blocco with. Restituisceselfper consentire l'accesso all'oggetto all'interno del blocco. Il metodo__exit__calcola il tempo trascorso all'uscita dal bloccowithe lo stampa.Approccio basato su funzioni
Se preferisci un approccio più conciso, magari a scapito della flessibilità, l'approccio basato su funzioni può essere una buona opzione. Qui usi il decorator
contextmanagerdel modulocontextlibper convertire qualsiasi funzione in un context manager.Vediamo come funziona:
Il decorator
@contextmanagertrasforma la funzione timer in un context manager. All'interno della funzione, viene catturatostart_time, e l'istruzioneyieldmette in pausa l'esecuzione, permettendo al codice nel bloccowithdi essere eseguito.Infine, la funzionalità di
__exit__è ottenuta catturando il tempo di fine e stampando il tempo trascorso.In sostanza, scrivi la logica di
__enter__prima della keywordyield, mentre la logica di__exit__viene dopo. Entrambi gli approcci raggiungono lo stesso risultato, ma la scelta dipende dalla tua preferenza per struttura e leggibilità.Esempi pratici di context manager
Ora che sai come scrivere context manager personalizzati in Python, vediamo alcuni esempi pratici in cui possono essere estremamente utili.
Gestione delle operazioni su file
Le operazioni su file sono un compito comune in molte applicazioni. Che si tratti di leggere o scrivere file, una gestione corretta garantisce integrità dei dati ed efficienza nell'uso delle risorse. Consideriamo uno scenario in cui vogliamo scrivere del testo su un file usando un context manager personalizzato.
In questo esempio, definiamo una classe
FileManagerper imitare la funzioneopendi Python che gestisce le operazioni sui file. Vediamo cosa fa ciascun metodo:__init__(self, filename, mode): Questo metodo è il costruttore della classe. Inizializza l'oggettoFileManagercon il nome file e la modalità forniti, che specificano il file da aprire e la modalità in cui aprirlo (ad esempio, lettura, scrittura, append).__enter__(self): Questo metodo viene chiamato all'ingresso del bloccowith, come sempre. Apre il file specificato dafilenamenella modalità specificata damode. L'oggetto file aperto viene assegnato aself.filee restituito per essere usato all'interno del bloccowith.__exit__(self, exc_type, exc_value, traceback): Questo metodo viene chiamato all'uscita dal blocco with, indipendentemente dal fatto che si sia verificata un'eccezione all'interno del blocco. Garantisce che il file venga chiuso correttamente chiamandoself.file.close()se self.file non èNone. Questo previene leak di risorse e assicura una corretta pulizia.Se ispezioni il contenuto di
example.txtdopo aver eseguito il codice sopra, dovresti vedere il testo scritto:Ovviamente, il vantaggio della classe
FileManagerè che puoi implementare qualsiasi logica personalizzata per lavorare con i file. Per esempio, puoi modificarla in modo che la classe tenga traccia, in un file di log, di quali file vengono aperti o chiusi.In questa versione modificata:
datetimeè importato per lavorare con i timestamp.log_actionper registrare le azioni sui file.log_filenameper specificare il nome del file di log. Il valore predefinito è'file_log.txt'.log_actionall'interno dei metodi__enter__e__exit__.log_action,datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")viene usato per ottenere il timestamp corrente nel formato"YYYY-MM-DD HH:MM:SS".Ora, se stampiamo il contenuto di
file_log.txt, dovremmo vedere i log:Un altro caso d'uso pratico che possiamo implementare come context manager personalizzato è uno strumento di gestione di database SQLite:
Anche questo imita la funzione
sqlite3.connect, ma può essere ulteriormente migliorato aggiungendo logica personalizzata di gestione del database. Verifichiamo se il manager funziona con alcune funzioni di esempio:Possiamo scrivere codice molto più manutenibile suddividendo le operazioni sul database in funzioni e usando il manager personalizzato che abbiamo appena creato.
Argomenti avanzati relativi ai context manager in Python
In questa sezione tratteremo argomenti avanzati relativi ai context manager in Python. Questi includono la gestione degli errori e l'annidamento dei context manager.
Gestione degli errori
La gestione degli errori è un aspetto essenziale della programmazione, e i context manager in Python offrono un modo pratico per gestire gli errori nelle operazioni di gestione delle risorse.
Nell'esempio della classe FileManager, la gestione degli errori può essere implementata all'interno del metodo
__exit__per garantire una corretta pulizia anche se si verifica un'eccezione. Per esempio, se si verifica un errore durante la scrittura del file (mentre siamo dentro il bloccowith), vogliamo comunque assicurarci che il file venga chiuso per evitare leak di risorse. Possiamo modificare il metodo__exit__come segue:Qui, chiudiamo prima il file usando
self.file.close()per garantire una corretta pulizia. Poi, verifichiamo se si è verificata un'eccezione(exc_type is not None). In tal caso, stampiamo un messaggio di errore per dare un riscontro su cosa sia andato storto.Qui:
exc_typeè la classe dell'eccezione, comeAttributeErroreIndexError.exc_valueè l'istanza dell'eccezione con il messaggio.tracebackè il traceback completo dell'errore.Eseguiamo la classe
FileManagercon un codice volutamente errato:Quindi, per implementare logiche personalizzate quando gestisci eccezioni nei tuoi manager, ecco un flusso di lavoro di esempio che puoi seguire:
Annidare i context manager
Annidare i context manager ti consente di gestire più risorse contemporaneamente, ciascuna con il proprio context manager, all'interno di una singola istruzione
with. Questo è particolarmente utile quando si affrontano operazioni complesse che coinvolgono più risorse. Vediamo come possiamo annidare i context manager nei nostri esempi.Considera uno scenario in cui vogliamo aprire un file ed eseguire operazioni sul database nello stesso contesto. Magari, vogliamo inserire il contenuto di un file CSV come righe in un database. Possiamo ottenere questo risultato annidando i context manager
FileManagereDatabaseConnectionnella stessa istruzionewith:In questo esempio, i context manager FileManager e DatabaseConnection sono annidati nella stessa istruzione
with. Questo ci permette di aprire il file e stabilire una connessione al database contemporaneamente. Le successive operazioni di scrittura su file e sul database vengono eseguite all'interno di questo contesto combinato.Una cosa da tenere a mente è la leggibilità del codice. Ti consiglierei che il numero di contesti simultanei non superi due.
Conclusione
I context manager in Python offrono un approccio strutturato alla gestione delle risorse all'interno di un'istruzione
with, garantendo una corretta allocazione e deallocazione delle risorse.In tutto il tutorial, abbiamo imparato le basi dei context manager, visto esempi pratici e discusso argomenti avanzati come la gestione degli errori e l'annidamento. Padroneggiando la scrittura di context manager personalizzati, potrai scrivere codice più pulito e affidabile, migliorare la gestione degli errori e gestire le risorse in modo efficiente.
L'argomento della scrittura di context manager personalizzati rientra nella categoria "Python avanzato". Ecco alcune risorse correlate per migliorare ulteriormente le tue competenze: