2013-05-18 11 views
6

La mia app ha una libreria audio personalizzata che utilizza essa stessa la libreria BASS.Tracciare un'eccezione ignorata in Python?

Io creo e distruggo oggetti flusso BASS in tutto il programma.

Quando le mie uscite del programma, in modo casuale (non ho ancora capito il motivo) ottengo il seguente avviso sulla mia console:

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

Biblioteca audio (audio/audio_player.py [classe Stream]) contiene una classe che crea un oggetto flusso BASS e quindi consente al codice di manipolarlo. Quando la classe viene distrutta (nella routine del) chiama BASS_StreamFree per cancellare tutte le risorse che BASS potrebbe aver assegnato.

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

La mia prima inclinazione in base a questo messaggio è che da qualche parte nel mio codice, un'istanza della mia classe flusso è orfano (non più assegnato a una variabile) e Python ancora sta cercando di chiamare la sua funzione del quando l'app si chiude, ma nel momento in cui tenta l'oggetto è andato via.

Questa app utilizza wxWidgets e pertanto implica alcune operazioni di threading. Il fatto che non mi venga assegnato un nome variabile effettivo mi porta a credere a ciò che ho affermato nel paragrafo precedente.

Non sono sicuro di quale codice sarebbe rilevante per eseguire il debug di questo. Il messaggio sembra innocuo, ma non mi piace l'idea di un'eccezione "ignorata" nel codice di produzione finale.

C'è qualche suggerimento che qualcuno ha per eseguire il debug di questo?

+0

"wxWidgets" Uh oh, aspettati che le cose vadano via quando non te l'aspetti, a meno che tu non lavori di più. –

risposta

7

Il messaggio che l'eccezione è stata ignorata è perché tutte le eccezioni generate in un metodo __del__ vengono ignorate per mantenere sano il modello di dati. Ecco la quota di competenza di the docs:

Attenzione: A causa delle circostanze precarie in cui vengono chiamati i metodi __del__(), eccezioni che si verificano durante la loro esecuzione vengono ignorati, e un avvertimento viene stampato sys.stderr invece. Inoltre, quando __del__() viene richiamato in risposta a un modulo in fase di eliminazione (ad esempio, quando viene eseguita l'esecuzione del programma), altri globali a cui fa riferimento il metodo __del__() potrebbero essere già stati eliminati o in fase di rimozione (ad esempio il meccanismo di importazione chiudere). Per questo motivo, i metodi __del__() dovrebbero fare il minimo assoluto necessario per mantenere invarianti esterni. A partire dalla versione 1.5, Python garantisce che i globali il cui nome inizia con un singolo trattino basso vengano cancellati dal loro modulo prima che vengano cancellati altri globali; se nessun altro riferimento a tali globalmente esiste, ciò può aiutare a garantire che i moduli importati siano ancora disponibili nel momento in cui viene chiamato il metodo __del__().

Come per il debug, si potrebbe iniziare mettendo un blocco try/except attorno al codice nel metodo __del__ e stampare ulteriori informazioni sullo stato del programma nel momento in cui si verifica. Oppure potresti considerare di fare di meno nel metodo __del__ o di eliminarlo completamente!

+0

Avevi ragione.L'eccezione era causata dal metodo '__del__'. Ho appena terminato la chiamata all'interno di un try/catch e ora tutto sembra buono. – fdmillion

Problemi correlati