2014-04-09 17 views
6

Nie mogę wywołać destruktora klasy Parent z destruktora klasy Child. Proszę sprawdzić poniższy kod:Python: nie można wywołać destruktora klasy nadrzędnej z super()

class BaseClass(object): 
    def __del__(self): 
     print 'BaseClass->Destructor' 

class DerivativeClass(BaseClass): 
    def __del__(self): 
     print 'DerivativeClass->Destructor' 
     #Invoke destructor of the base class, it works 
     BaseClass.__del__(self)   
     #Doesn't work 
     #super(DerivativeClass, self).__del__() 

instance = DerivativeClass() 

Gdy używam super(DerivativeClass, self).__del__() w DerivativeClass.__del__() mam następujący błąd:

Exception TypeError: 'must be type, not None' in <bound method 
DerivativeClass.__del__ of <__main__.DerivativeClass object at 0xb73a682c>> ignored 

PYTANIE:

Dlaczego nie mogę korzystać super w destruktor klasy potomnej, podczas gdy w konstruktorze klasy potomnej jest idealnie czysty?

+1

Nie jestem pewien dokładnego powodu, ale zauważ, że 'super (DerivativeClass, self)' zwraca obiekt typu 'super', a nie instancji' BaseClass'. '__del__' prawdopodobnie zawiera pewne założenie co do pierwszego argumentu, który nie jest prawidłowy dla obiektów' super'. – chepner

+1

Umieść 'print (DerivativeClass)' przed 'super ...', a zobaczysz, co się dzieje. – Hyperboreus

+1

Lub dodaj "del instance" jako ostatni wiersz do kodu, aby upewnić się, że instancja zostanie usunięta, zanim klasa przejdzie przez Jordan. – Hyperboreus

Odpowiedz

5

Wygląda na to, że dzieje się tak tylko podczas zamykania środowiska wykonawczego (ponieważ DerivativeClass to None).

Działa to dobrze:

class BaseClass(object): 
    def __del__(self): 
     print 'BaseClass->Destructor' 

class DerivativeClass(BaseClass): 
    def __del__(self): 
     print 'DerivativeClass->Destructor' 
     super(DerivativeClass, self).__del__() 

instance = DerivativeClass() 
del instance 

I działa to zbyt dobrze:

class BaseClass(object): 
    def __del__(self): 
     print 'BaseClass->Destructor' 

class DerivativeClass(BaseClass): 
    def __del__(self): 
     print 'DerivativeClass->Destructor' 
     super(type(self), self).__del__() 

instance = DerivativeClass() 

Również w tym:

class BaseClass(object): 
    def __del__(self): 
     print 'BaseClass->Destructor' 

class DerivativeClass(BaseClass): 
    def __del__(self): 
     print 'DerivativeClass->Destructor' 
     super(DerivativeClass, self).__del__() 

def someScope(): 
    instance = DerivativeClass() 

someScope() 

W fragmentów 1 i 3, I upewnij się, że instancja umiera przed klasą. W drugim fragmencie omawiam całą sprawę w dość brzydki sposób.

+1

To ma sens, ponieważ zachowanie po wyjściu z programu jest dość nieprzewidywalne. – Konstantin

+2

+1 Wspólnym wątkiem we wszystkich trzech przykładach jest to, że unikają używania nazwy globalnej, która (prawdopodobnie) nie jest już w zakresie, kiedy interpreter wychodzi. – chepner

Powiązane problemy