2013-05-18 17 views
6

Moja aplikacja ma niestandardową bibliotekę audio, która sama używa biblioteki BASS.Śledzenie ignorowanego wyjątku w Pythonie?

Tworzę i niszczę obiekty strumienia BASS w całym programie.

Kiedy moi program wychodzi, losowo (I nie zorientowali się jeszcze wzorzec) pojawia się następujący komunikat na mojej konsoli:

Exception TypeError: "'NoneType' object is not callable" in <bound method stream.__del__ of <audio.audio_player.stream object at 0xaeda2f0>> ignored 

moja biblioteka dźwięku (audio/audio_player.py [klasa Stream]) zawiera klasę, która tworzy obiekt strumienia BASS, a następnie umożliwia manipulowanie nim przez kod. Gdy klasa zostanie zniszczona (w procedurze del), wywołuje funkcję BASS_StreamFree w celu wyczyszczenia dowolnych zasobów przydzielonych przez BASS.

(audio_player.py)

from pybass import * 
from ctypes import pointer, c_float, c_long, c_ulong, c_buffer 
import os.path, time, threading 

# initialize the BASS engine 
BASS_Init(-1, 44100, 0, 0, None) 

class stream(object): 
    """Represents a single audio stream""" 
    def __init__(self, file): 
     # check for file existence 
     if (os.path.isfile(file) == False): 
      raise ValueError("File %s not found." % file) 
     # initialize a bass channel 
     self.cAddress = BASS_StreamCreateFile(False, file, 0, 0, 0) 
    def __del__(self): 
     BASS_StreamFree(self.cAddress) 
    def play(self): 
     BASS_ChannelPlay(self.cAddress, True) 
     while (self.playing == False): 
      pass 
    ..more code.. 

Moim pierwszym skojarzeniem na podstawie tej wiadomości jest to, że gdzieś w moim kodu, wystąpienie mojej klasie strumień jest osierocony (już przypisana do zmiennej) i nadal Python próbuje zadzwonić do funkcji del, gdy aplikacja się zamyka, ale do czasu, gdy spróbuje, obiekt zniknął.

Ta aplikacja używa wxWidgets i tym samym wiąże się z niektórymi wątkami. Fakt, że nie otrzymuję rzeczywistej nazwy zmiennej, pozwala mi uwierzyć w to, co napisałem w poprzednim akapicie.

Nie jestem pewien, jaki kod byłby odpowiedni do debugowania tego. Wiadomość wydaje się nieszkodliwa, ale nie podoba mi się pomysł "ignorowanego" wyjątku w ostatecznym kodzie produkcyjnym.

Czy są jakieś wskazówki, które ktoś ma do debugowania tego?

+0

"wxWidgets" Uh, och, oczekuj, że rzeczy odejdą, kiedy nie będziesz tego oczekiwał, chyba że wykonasz więcej pracy. –

Odpowiedz

7

Komunikat o tym, że wyjątek został zignorowany, jest taki, że wszystkie wyjątki podniesione w metodzie __del__ są ignorowane, aby zachować model danych przy zdrowych zmysłach. Oto odnośny fragment the docs:

Ostrzeżenie: Z powodu niepewnych okoliczności, w których __del__() metody są wywoływane, wyjątków, które występują 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__().

Jak do debugowania go, można uruchomić poprzez umieszczenie try/except blok wokół kodu w metodzie __del__ i drukowanie informacji o stanie programu w momencie jego wystąpienia. Lub możesz rozważyć zrobienie mniej w metodzie __del__ lub całkowite pozbycie się go!

+0

Miałeś rację.Wyjątek był spowodowany w metodzie "__del__". Właśnie zawarłem wezwanie w try/catch i wszystko wydaje się teraz dobre. – fdmillion