2013-05-18 2 views
6

Мое приложение имеет собственную аудио-библиотеку, которая сама использует библиотеку BASS.Отслеживание игнорируемого исключения в Python?

Я создаю и уничтожаю объекты потока BASS по всей программе.

Когда моя программа выходит, случайно (я не понял, шаблон еще) я получаю следующее уведомление на моей консоли:

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

Моя аудио библиотеки (аудио/audio_player.py [класс потока]) содержит класс, который создает объект потока BASS, а затем позволяет коду манипулировать им. Когда класс уничтожается (в процедуре del), он вызывает BASS_StreamFree для очистки любых ресурсов, которые 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.. 

Мой первый наклон на основе этого сообщения в том, что где-то в моем коде, экземпляр моего класса потока не сиротства (больше не присваивается переменная) и Python еще пытается вызвать функцию del, когда приложение закрывается, но к тому моменту, когда он пытается, объект ушел.

Это приложение действительно использует wxWidgets и, следовательно, использует некоторые потоки. Тот факт, что мне не дано фактическое имя переменной, заставляет меня поверить в то, что я сказал в предыдущем абзаце.

Я не уверен, какой именно код будет иметь отношение к отладке этого. Сообщение кажется безобидным, но мне не нравится идея «проигнорированного» исключения в конечном производственном коде.

Есть ли какие-либо советы для отладки?

+0

«wxWidgets» О, ожидайте, что материал исчезнет, ​​когда вы этого не ожидаете, если не сделаете больше работы. –

ответ

7

Сообщение о том, что исключение было проигнорировано, связано с тем, что все исключения, вызванные методом __del__, игнорируются, чтобы сохранить модель данных разумной. Вот соответствующая часть the docs:

Предупреждение: Из-за нестабильных условий, при которых вызываются __del__() методы, исключения, которые происходят во время их исполнения, игнорируются, и выводится предупреждение в sys.stderr вместо этого. Кроме того, когда __del__() вызывается в ответ на удаляемый модуль (например, при выполнении программы), другие глобальные переменные, на которые ссылается метод __del__(), могут быть уже удалены или в процессе их снесения (например, импортная техника Выключение). По этой причине методы __del__() должны выполнять абсолютный минимум, необходимый для поддержания внешних инвариантов. Начиная с версии 1.5, Python гарантирует, что глобальные имена, имена которых начинаются с одного символа подчеркивания, удаляются из их модуля до удаления других глобальных символов; если нет других ссылок на такие глобальные глобальные переменные, это может помочь гарантировать, что импортированные модули все еще доступны в момент вызова метода __del__().

Что касается отладки, вы могли бы начать, поставив блок try/except вокруг кода в методе __del__ и распечатывания больше информации о состоянии программы на момент ее возникновения. Или вы можете рассмотреть возможность сделать меньше в методе __del__ или полностью избавиться от него!

+0

Вы были правы.Исключение было вызвано методом '__del__'. Я просто завернул вызов внутри try/catch, и теперь все кажется хорошим. – fdmillion

Смежные вопросы