2015-09-07 16 views
7

un semplice esempio:Python strano multiprocessing con nome di variabile

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import multiprocessing 

class Klass(object): 
    def __init__(self): 
     print "Constructor ... %s" % multiprocessing.current_process().name 

    def __del__(self): 
     print "... Destructor %s" % multiprocessing.current_process().name 


if __name__ == '__main__': 
    kls = Klass() 

corsa con errore quando fare current_process in __del__:

Constructor ... MainProcess 
Exception AttributeError: "'NoneType' object has no attribute 'current_process'" in <bound method Klass.__del__ of <__main__.Klass object at 0x7f5c34e52090>> ignored 

se cambio un nome di variabile:

als = Klass() 

ottiene il risultato giusto:

Constructor ... MainProcess 
... Destructor MainProcess 

e ho provato molti nomi di variabili, alcuni ok, qualche errore.

Perché nome di istanza diverso, il modulo di multiprocessing sarà None in __del__?

+0

Vedo lo stesso risultato ... è molto strano! – jonrsharpe

+1

Lo stesso qui. Produce gli stessi risultati strani. Quindi immagino che tu abbia individuato un bug in "multiprocessing". – Sait

+0

@jonrsharpe vedi la risposta di unutbu –

risposta

9

Il codice solleva

AttributeError: "'NoneType' object has no attribute 'current_process'" 

se la variabile globale multiprocessing viene eliminato prima kls viene eliminato. In generale, l'ordine in cui gli oggetti vengono eliminati non è prevedibile. Tuttavia, per the docs:

A partire dalla versione 1.5, garantisce Python che globali il cui nome inizia con un singolo trattino basso vengono eliminati dal loro modulo prima di altre variabili globali sono soppressi; se nessun altro riferimento a tali globalmente esiste, ciò può aiutare a garantire che i moduli importati siano ancora disponibili nel momento in cui viene chiamato il metodo __del__().

Pertanto, se il nome l'istanza _kls (con un trattino basso), allora si può essere certi che la sua __del__ sarà chiamato prima multiprocessing viene eliminato:

import multiprocessing 

class Klass(object): 
    def __init__(self): 
     print "Constructor ... %s" % multiprocessing.current_process().name 

    def __del__(self): 
     print "... Destructor %s" % multiprocessing.current_process().name 


if __name__ == '__main__': 
    _kls = Klass() 

rendimenti

Constructor ... MainProcess 
... Destructor MainProcess 

Other methods di garantire un del metodo viene chiamato prima che il modulo è soppresso includono

  • utilizzando atexit
  • attraverso un gestore contesto
  • salvare un riferimento al modulo come attributo di Klass.
+0

molto grazie! Dovrei prestare maggiore attenzione alla sezione * warning * del documento python. –

Problemi correlati