In Pitone, con dichiarazione viene utilizzato nella gestione delle eccezioni per rendere il codice più pulito e molto più leggibile. Semplifica la gestione delle risorse comuni come i flussi di file. Osservare il seguente esempio di codice su come l'uso dell'istruzione with rende il codice più pulito.
Python3
ordine casuale sql
# file handling> # 1) without using with statement> file> => open>(>'file_path'>,>'w'>)> file>.write(>'hello world !'>)> file>.close()> # 2) without using with statement> file> => open>(>'file_path'>,>'w'>)> try>:> >file>.write(>'hello world'>)> finally>:> >file>.close()> |
>
>
Python3
# using with statement> with>open>(>'file_path'>,>'w'>) as>file>:> >file>.write(>'hello world !'>)> |
>
>
Si noti che, a differenza delle prime due implementazioni, non è necessario chiamare file.close() quando si utilizza with istruzione. L'istruzione with stessa garantisce la corretta acquisizione e rilascio delle risorse. Un'eccezione durante la chiamata a file.write() nella prima implementazione può impedire la chiusura corretta del file, il che potrebbe introdurre diversi bug nel codice, ovvero molte modifiche nei file non diventano effettive finché il file non viene chiuso correttamente. Il secondo approccio nell'esempio precedente si occupa di tutte le eccezioni ma l'utilizzo dell'istruzione with rende il codice compatto e molto più leggibile. Pertanto, with istruzione aiuta a evitare bug e perdite garantendo che una risorsa venga rilasciata correttamente quando il codice che utilizza la risorsa viene completamente eseguito. L'istruzione with è comunemente utilizzata con flussi di file, come mostrato sopra e con lock, socket, sottoprocessi e telnet ecc.
rdbms
Supportare l'istruzione with negli oggetti definiti dall'utente
Non c'è nulla di speciale in open() che lo renda utilizzabile con l'istruzione with e la stessa funzionalità può essere fornita negli oggetti definiti dall'utente. Il supporto con la dichiarazione nei tuoi oggetti ti garantirà di non lasciare mai nessuna risorsa aperta. Per utilizzare l'istruzione with negli oggetti definiti dall'utente è sufficiente aggiungere i metodi __enter__() e __exit__() nei metodi dell'oggetto. Consideriamo il seguente esempio per ulteriori chiarimenti.
Python3
# a simple file writer object> class> MessageWriter(>object>):> >def> __init__(>self>, file_name):> >self>.file_name>=> file_name> > >def> __enter__(>self>):> >self>.>file> => open>(>self>.file_name,>'w'>)> >return> self>.>file> >def> __exit__(>self>,>*>args):> >self>.>file>.close()> # using with statement with MessageWriter> with MessageWriter(>'my_file.txt'>) as xfile:> >xfile.write(>'hello world'>)> |
>
>
Esaminiamo il codice sopra. Se noti, ciò che segue la parola chiave with è il costruttore di MessageWriter. Non appena l'esecuzione entra nel contesto dell'istruzione with viene creato un oggetto MessageWriter e Python chiama quindi il metodo __enter__(). In questo metodo __enter__(), inizializza la risorsa che desideri utilizzare nell'oggetto. Questo metodo __enter__() dovrebbe sempre restituire un descrittore della risorsa acquisita. Cosa sono i descrittori delle risorse? Questi sono gli handle forniti dal sistema operativo per accedere alle risorse richieste. Nel seguente blocco di codice, file è un descrittore della risorsa del flusso di file.
dove si trovano le impostazioni del browser
Pitone
file> => open>(>'hello.txt'>)> |
>
>
Nell'esempio MessageWriter fornito sopra, il metodo __enter__() crea un descrittore di file e lo restituisce. Il nome xfile qui viene utilizzato per fare riferimento al descrittore di file restituito dal metodo __enter__(). Il blocco di codice che utilizza la risorsa acquisita viene inserito all'interno del blocco dell'istruzione with. Non appena viene eseguito il codice all'interno del blocco with, viene chiamato il metodo __exit__(). Tutte le risorse acquisite vengono rilasciate nel metodo __exit__(). Questo è il modo in cui utilizziamo l'istruzione with con oggetti definiti dall'utente. Questa interfaccia dei metodi __enter__() e __exit__() che fornisce il supporto dell'istruzione with negli oggetti definiti dall'utente è chiamata Gestore del contesto .
Il modulo contextlib
Un gestore di contesto basato su classi come mostrato sopra non è l'unico modo per supportare l'istruzione with negli oggetti definiti dall'utente. IL contestolib Il modulo fornisce alcune altre astrazioni basate sull'interfaccia di gestione del contesto di base. Ecco come possiamo riscrivere il gestore del contesto per l'oggetto MessageWriter utilizzando il modulo contextlib.
Python3
quante città ci sono in noi
from> contextlib>import> contextmanager> class> MessageWriter(>object>):> >def> __init__(>self>, filename):> >self>.file_name>=> filename> >@contextmanager> >def> open_file(>self>):> >try>:> >file> => open>(>self>.file_name,>'w'>)> >yield> file> >finally>:> >file>.close()> # usage> message_writer>=> MessageWriter(>'hello.txt'>)> with message_writer.open_file() as my_file:> >my_file.write(>'hello world'>)> |
>
>
In questo esempio di codice, a causa di prodotto nella sua definizione, la funzione open_file() è a funzione del generatore . Quando viene chiamata questa funzione open_file(), crea un descrittore di risorsa denominato file. Questo descrittore di risorsa viene quindi passato al chiamante ed è qui rappresentato dalla variabile my_file. Dopo che il codice all'interno del blocco with è stato eseguito, il controllo del programma ritorna alla funzione open_file(). La funzione open_file() riprende la sua esecuzione ed esegue il codice successivo all'istruzione yield. Questa parte di codice che appare dopo la dichiarazione di rendimento rilascia le risorse acquisite. Il @contextmanager qui è un decoratore . La precedente implementazione basata su classi e questa implementazione basata su generatore di gestori di contesto sono internamente le stesse. Anche se quest'ultimo sembra più leggibile, richiede la conoscenza di generatori, decoratori e resa.