2015-10-09 12 views
6

Kiedy jest odebrana zmienna śmieci poniżej zmiennej python? Spodziewałem się wyświetlenia komunikatu ze zmiennej statycznej foo destructor.Python zmienna statyczna deallocation

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() 

Wyjście jest (Python 2.7):

Foo init running 
Bar init running 
Destructor Bar 

Spodziewałem:

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

Nie jest to duplikat dla mnie. Drugie pytanie dotyczy "odwołań kołowych". – luoluo

+2

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

+0

Co to jest "zmienna statyczna Pythona"? Czy ta koncepcja istnieje? –

Odpowiedz

3

więc spodziewamy odniesienie do obiektu foo zostać usunięte, gdy Barklasa została usunięta. I ogólnie to się dzieje. Jeśli spróbujesz

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 

uzyskać

Foo init running 
Bar init running 
Destructor Bar 
Destructor Foo 

i widać oba destruktory nazywane zarówno w Pythonie 2.7 i Python 3.4. Jednak w Pythonie 2.7, Bar nie jest prawidłowo niszczony podczas zamykania programu. Jak docs powiedzieć:

Nie jest zagwarantowane, że del() metody są nazywane dla obiektów, które nadal istnieją, kiedy wyjść tłumacza.

Dlaczego Bar nie jest niszczony podczas wyjścia z interpretera?

Prawdopodobnie klasa w Pythonie 2.7 nie jest niszczona z powodu odwołań kołowych (patrz poniżej). W Pythonie 3.4 (po PEP 442) obiekty z odwołaniami kołowymi są niezawodnie niszczone (nawet jeśli mają metody __del__), co może wyjaśniać zmianę.

Jednak to nie wyjaśnia całkowicie różnicy, ponieważ chociaż klasa jest w cyklu odniesienia, sama klasa nie ma destruktora.

Wygląda na to, że w Pythonie 2 obiekty z odwołaniami kołowymi nie są niezawodnie niszczone podczas zamykania interpretera, podczas gdy są w Pythonie 3.4. Podaję więcej informacji here.

edycji (więcej szczegółów na temat odniesienia okrągłych)

klasy zawierają referencje cykliczne z powrotem na siebie, z jednej strony przez ich słownika:

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

a po drugie poprzez szczegółach MRO:

MyClass in MyClass.__mro__ 
+0

To nie wyjaśnia, dlaczego nie zostało usunięte. – luoluo

+0

Jest to funkcja Pythona 2.7, ale nie rozumiem w pełni racjonalnego projektu. – strubbly

+0

Hmm - więcej myśli i wymyśliłem wiarygodne wyjaśnienie. – strubbly

Powiązane problemy