2013-08-05 44 views
10

Mam obiekt klasy python i chcę, aby przypisać wartość jednej klasy zmiennejPython AttributeError na __del__

class Groupclass(Workerclass): 
    """worker class""" 
    count = 0 

    def __init__(self): 
     """initialize time""" 
     Groupclass.count += 1 
     self.membercount = 0; 
     self.members = [] 

    def __del__(self): 
     """delte a worker data""" 
     Groupclass.count -= 1 


if __name__ == "__main__": 
    group1 = Groupclass() 

Ten wynik wykonanie jest poprawne, ale jest komunikat o błędzie, który mówi:

Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Groupclass.__del__ of <__main__.Groupclass instance at 0x00BA6710>> ignored 

Czy ktoś może mi powiedzieć, co zrobiłem źle?

+1

Twoja klasa bazowa 'Workerclass' wydaje się mieć metodę' __del__', która próbuje coś zrobić z 'count', ale nie udostępniłeś tej metody tutaj. –

+0

Przepraszam, nie wiem, że to związane ... –

+0

Twoja wiadomość jest tylko ostrzeżeniem, to nie jest błąd. ** Coś ** w metodzie '__del__' próbowało zrobić coś z atrybutem' count' i nie powiodło się. –

Odpowiedz

13

Twoja metoda __del__ zakłada, że ​​klasa jest nadal obecna do czasu jej wywołania.

To przypuszczenie jest nieprawidłowe. Groupclass został już wyczyszczony po wyjściu z programu w Pythonie i jest teraz ustawiony na None.

testu jeśli globalna odniesienie do klasy nadal istnieje pierwszy:

def __del__(self): 
    if Groupclass: 
     Groupclass.count -= 1 

lub użyj type() aby uzyskać lokalną odniesienia:

def __del__(self): 
    type(self).count -= 1 

ale należy pamiętać, że oznacza to, że semantykę dla count zmień jeśli podklasa Groupclass jest podklasowana (każda podklasa otrzymuje atrybut .count, a tylko Groupclass ma atrybut .count).

Cytując z dokumentacji __del__ Hak:

Ostrzeżenie: Ze względu na niepewne warunki, w jakich __del__() metody wywoływane są wyjątki, które pojawiają się w trakcie ich realizacji są ignorowane, a ostrzeżenia drukowane na sys.stderr zamiast . Ponadto, gdy wywoływane jest __del__() w odpowiedzi na usuwany moduł (np. Po wykonaniu programu), inne globale, do których odwołuje się metoda __del__(), mogły już zostać usunięte lub są w trakcie rozbierania (np. wyłączanie). Z tego powodu metody powinny wykonywać absolutne minimum potrzebne do zachowania zewnętrznych niezmienników. Począwszy od wersji 1.5, Python gwarantuje, że globale, których nazwa zaczyna się od jednego podkreślenia, są usuwane z ich modułu, zanim inne globale zostaną usunięte; jeśli nie ma innych odniesień do takich globaliów, może to pomóc w zapewnieniu, że importowane moduły są nadal dostępne w czasie, gdy wywoływana jest metoda __del__().

Jeśli używasz Python 3, stosuje się dwa dodatkowe noty:

  • CPython 3.3 automatycznie stosuje randomized hash salt do str kluczy używanych w słowniku globals; wpływa to również na kolejność, w której globale są czyszczone, i może być , że widzisz problem tylko na niektórych z przebiegów.

  • CPython 3.4 nie ustawia już globali na None (w większości przypadków), jak na Safe Object Finalization; patrz PEP 442.

+0

Dziękuję, że działa. Teraz moje pytanie brzmi, czy chcę "del" obiektu 'GroupClass', obiekt' Groupclass' lub 'Groupclass' musi istnieć przed wykonaniem 'del', więc wydaje się, że instrukcja jest w jakiś sposób nadmiarowa? –

+0

@Chandler: Nie, kiedy istnieje tłumacz, nazwy globalne można wyczyścić przed wystąpieniem instancji; nazwa "Groupclass" została już wyczyszczona. Możesz także użyć 'type (self) .count', chyba że masz podklasy, które nie mają własnej liczby. –

+0

wciąż nie do końca rozumiem tę koncepcję, ale dzięki temu przyjrzę się temu! –