2015-10-09 6 views
6

Quando viene raccolta la garbage variable delle classi statiche python di sotto? Mi aspettavo di vedere il messaggio dalla variabile statica foo destructor.Dealer variabile statica Python

class Foo(object): 
    def __init__(self): 
     print "Foo init running" 

    def __del__(self): 
     print "Destructor Foo" 

class Bar(object): 
    foo = Foo() 
    def __init__(self): 
     print "Bar init running" 

    def __del__(self): 
     print "Destructor Bar" 

bar_obj = Bar() 

l'uscita è (Python 2.7):

Foo init running 
Bar init running 
Destructor Bar 

mi aspettavo:

Foo init running 
Bar init running 
Destructor Foo 
Destructor Bar 
+0

Non uno duplicato per me. L'altra domanda riguarda i "riferimenti circolari". – luoluo

+2

https://stackoverflow.com/questions/14628486/why-arent-destructors-guaranteed-to-be-called-on-interpreter-exit –

+0

E cos'è una "variabile statica Python"? Questo concetto esiste? –

risposta

3

Così ci si aspetterebbe il riferimento all'oggetto foo da eliminare quando il Barclasse viene cancellata. E questo è generalmente ciò che accade. Se si tenta

class Foo(object): 
    def __init__(self): 
     print("Foo init running") 

    def __del__(self): 
     print("Destructor Foo") 

class Bar(object): 
    foo = Foo() 
    def __init__(self): 
     print("Bar init running") 

    def __del__(self): 
     print("Destructor Bar") 


def f(): 
    bar_obj = Bar() 

f() 
del Bar 

ottengo

Foo init running 
Bar init running 
Destructor Bar 
Destructor Foo 

e si può vedere entrambi i distruttori chiamate sia in Python 2.7 e Python 3.4. Tuttavia, in Python 2.7, Bar non viene correttamente distrutto durante la chiusura del programma. Come i documenti dicono:

Non è garantito che del (metodi) sono chiamati per gli oggetti che ancora esistono quando le uscite interprete.

Perché lo Bar non viene distrutto durante l'uscita dall'interprete?

Sembra probabile che la classe in Python 2.7 non venga distrutta a causa di riferimenti circolari (vedere di seguito). In Python 3.4 (dopo PEP 442) gli oggetti con riferimenti circolari vengono distrutti in modo affidabile (anche se hanno i metodi __del__) e ciò potrebbe spiegare la modifica.

Tuttavia, questo non spiega completamente la differenza perché sebbene la classe sia in un ciclo di riferimento, la classe stessa non ha un distruttore.

Sembra che in Python 2 gli oggetti con riferimenti circolari non vengano distrutti in modo affidabile durante l'uscita dell'interprete, mentre sono in Python 3.4. Fornisco ulteriori informazioni here.

Edit (maggiori dettagli sui riferimenti circolari):

classi contengono riferimenti ciclici di nuovo a se stessi, in primo luogo tramite il loro dizionario:

MyClass.__dict__['__dict__'].__objclass__ == MyClass 

e in secondo luogo attraverso i loro dettagli MRO:

MyClass in MyClass.__mro__ 
+0

Questo non spiega perché non è stato eliminato. – luoluo

+0

È una funzionalità di Python 2.7 ma non capisco appieno la logica del design. – strubbly

+0

Hmm - più pensiero e ho trovato una spiegazione plausibile – strubbly