跟踪Python中被忽略的异常? [英] Tracing an ignored exception in Python?

查看:126
本文介绍了跟踪Python中被忽略的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序具有一个自定义音频库,该库本身使用BASS库.

My app has a custom audio library that itself uses the BASS library.

我在整个程序中创建和销毁BASS流对象.

I create and destroy BASS stream objects throughout the program.

程序退出时,随机地(我还没有弄清楚模式)在控制台上收到以下通知:

When my program exits, randomly (I haven't figured out the pattern yet) I get the following notice on my console:

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

我的音频库(audio/audio_player.py [class Stream])包含一个类,该类创建BASS流对象,然后允许代码对其进行操作.当类被销毁时(在 del 例程中),它将调用BASS_StreamFree清除BASS可能分配的任何资源.

My audio library (audio/audio_player.py [class Stream]) contains a class that creates a BASS stream object and then allows the code to manipulate it. When the class is destroyed (in the del routine) it calls BASS_StreamFree to clear any resources BASS might have allocated.

(audio_player.py)

(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 在应用关闭时起作用,但是在尝试关闭时,该对象消失了.

My first inclination based on this message is that somewhere in my code, an instance of my stream class is being orphaned (no longer assigned to a variable) and Python still is trying to call its del function when the app closes, but by the time it tries the object has gone away.

此应用程序确实使用wxWidgets,因此涉及一些线程.没有给我一个实际的变量名这一事实使我相信我在上一段中所说的.

This app does use wxWidgets and thus involves some threading. The fact that I'm not being given an actual variable name leads me to believe what I stated in the previous paragraph.

我不确定确切的代码与调试有关.该消息似乎无害,但我不喜欢最终生产代码中被忽略"异常的想法.

I'm not sure exactly what code would be relevant to debug this. The message does seem harmless but I don't like the idea of an "ignored" exception in the final production code.

有人有调试技巧吗?

推荐答案

忽略该异常的消息是因为忽略了__del__方法中引发的所有异常,以保持数据模型的健全.这是文档的相关部分:

The message that the exception was ignored is because all exceptions raised in a __del__ method are ignored to keep the data model sane. Here's the relevant portion of the docs:

警告::由于在调用__del__()方法的情况不稳定,在执行过程中发生的异常将被忽略,并向sys.stderr显示警告.同样,当响应删除模块而调用__del__()时(例如,当执行程序时),__del__()方法引用的其他全局变量可能已经被删除或正在被拆除(例如进口机械关闭).因此,__del__()方法应该执行维护外部不变式所需的绝对最小值.从版本1.5开始,Python保证在删除其他全局变量之前,先从其模块中删除名称以单个下划线开头的全局变量.如果没有其他对此类全局变量的引用,则可能有助于确保在调用__del__()方法时导入的模块仍然可用.

Warning: Due to the precarious circumstances under which __del__() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when __del__() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the __del__() method may already have been deleted or in the process of being torn down (e.g. the import machinery shutting down). For this reason, __del__() methods should do the absolute minimum needed to maintain external invariants. Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the __del__() method is called.

对于调试它,您可以先在__del__方法中的代码周围放置一个try/except块,然后在程序出现时打印出有关程序状态的更多信息.或者,您可以考虑在__del__方法中做更少的事情,或者完全摆脱它!

As for debugging it, you could start by putting a try/except block around the code in your __del__ method and printing out more information about the program's state at the time it occurs. Or you could consider doing less in the __del__ method, or getting rid of it entirely!

这篇关于跟踪Python中被忽略的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆