Domanda

Sto cercando di capire l'istruzione with in Python.Ovunque guardi si parla di apertura e chiusura di un file e intende sostituire il blocco try-finally.Qualcuno potrebbe postare anche altri esempi.Sto solo provando la fiaschetta e ci sono molte dichiarazioni al suo interno.Sicuramente chiedo a qualcuno di fornire un po' di chiarezza in merito.

È stato utile?

Soluzione

C'è una bella spiegazione qui . In sostanza, l'istruzione with chiama due metodi speciali per l'oggetto associato. I __enter__ e __exit__ metodi. Il immettere metodo restituisce la variabile associata con il "con" dichiarazione. Mentre il metodo __exit__ viene chiamato dopo le esegue statement per gestire qualsiasi pulizia (come ad esempio la chiusura di un puntatore a file).

Altri suggerimenti

L'idea della dichiarazione with è quello di rendere "fare la cosa giusta" il percorso di minor resistenza. Mentre l'esempio di file è il più semplice, infilare serrature effettivamente fornire un più classico esempio di codice non-buggy, ovviamente:

try:
    lock.acquire()
    # do stuff
finally:
    lock.release()

Questo codice è rotto - se l'acquisizione di blocco mai fallisce, sia l'eccezione sbagliato sarà gettato (in quanto il codice tenterà di rilasciare un blocco che non è mai acquisito), o, peggio ancora, se questo è un blocco ricorsivo, è sarà rilasciato presto. Gli sguardi codice corretto come questo:

lock.acquire()
try:
    # do stuff
finally:
    # If lock.acquire() fails, this *doesn't* run
    lock.release()

Utilizzando una dichiarazione with, diventa impossibile ottenere questo torto, siccome è integrato nel contesto manager:

with lock: # The lock *knows* how to correctly handle acquisition and release
  # do stuff

L'altro luogo dove l'istruzione with aiuta molto simile al vantaggio principale di decoratori funzione e classe: ci vuole codice "a due pezzi", che possono essere separati da un numero arbitrario di linee di codice (la definizione della funzione decoratori , il blocco try nel caso attuale) e lo trasforma in codice di "One piece" in cui il programmatore dichiara semplicemente in anticipo quello che stanno cercando di fare.

Per esempi breve, questo non sembra un grande guadagno, ma fa davvero una grande differenza in sede di revisione del codice. Quando vedo lock.acquire() in un pezzo di codice, ho bisogno di scorrere verso il basso e verificare la presenza di un corrispondente lock.release(). Quando vedo with lock:, però, non è necessaria alcuna tale verifica -. Vedo subito che il blocco sarà rilasciato correttamente

Ci sono dodici esempi di utilizzo with In PEP343, incluso l'esempio di apertura del file:

  1. Un modello per garantire che un blocco, acquisito all'inizio di un blocco, viene rilasciato quando il blocco viene lasciato
  2. Un modello per l'apertura di un file che garantisce che il file sia chiuso quando il blocco viene lasciato
  3. Un modello per commettere o far ripristinare una transazione di database
  4. Esempio 1 riscritto senza generatore
  5. Reindirizzare temporaneamente lo stdout
  6. Una variante di open() che restituisce anche una condizione di errore
  7. Un altro esempio utile sarebbe un'operazione che blocca i segnali
  8. Un altro utilizzo di questa funzionalità è il contesto decimale
  9. Ecco un semplice gestore di contesto per il modulo decimale
  10. Un generico gestore di contesto di "chiusura di oggetti".
  11. un contestorelease() per rilasciare temporaneamente un blocco precedentemente acquisito scambiando le chiamate acquire() e release()
  12. Un contesto "nidificato" che nidifica automaticamente i contesti forniti da sinistra a destra per evitare un'eccessiva rientranza
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top