2012-05-29 9 views
5

Ho una domanda su questo sul test del seguente codice:quando rilasciare i dati dello stack di funzioni in python?

1,

def file_close_test(): 
    f = open('/tmp/test', 'w+') 

if __name__ == '__main__': 
    file_close_test() 
    # wait to see whether file closed. 
    import time 
    time.sleep(30) 

2,

def file_close_on_exc_test(): 
    f = open('/tmp/test', 'w+') 
    raise Exception() 

def exception_wrapper(): 
    try: 
     file_close_on_exc_test() 
    except: 
     pass 
    # wait to see whether file closed. 
    import time 
    time.sleep(10) 

if __name__ == '__main__': 
    exception_wrapper() 
    import time 
    time.sleep(30) 
  1. L'oggetto file chiuso quando i file_close_test uscite perché nessuno riferimento ad esso.
  2. Dopo l'eccezione sollevata, l'oggetto file non è chiuso.so penso che i relativi dati dello stack non siano stati rilasciati.
  3. Dopo l'uscita exception_wrapper, il file si chiude automaticamente.

puoi spiegare questo per me? Grazie.

risposta

3

L'eccezione include un oggetto traceback che può essere utilizzato per accedere a tutte le variabili locali in qualsiasi frame dello stack attivo quando è stata generata l'eccezione. Ciò significa che puoi ancora accedere al file fino a quando il contesto di eccezione non viene cancellato.

Anche dopo la sleep() alla fine del exception_wrapper è possibile utilizzare sys.exc_info per arrivare al file aperto in questo modo:

tb = sys.exc_info()[2] 
print tb.tb_next.tb_frame.f_locals['f'] 

Tutto questo è ovviamente specifico per la particolare implementazione di Python che si sta utilizzando. Altre implementazioni potrebbero non chiudere in modo implicito i file finché non vengono raccolti.

La linea di fondo è che non dovresti mai dipendere dal conteggio dei riferimenti di Python o dalla garbage collection per ripulire risorse come i file aperti, fallo sempre esplicitamente.

+1

Non è nemmeno così difficile: 'con open ('/ tmp/test', 'w +') come f:' –

+0

mi aiuta molto, grazie :) – yancl

Problemi correlati