在异常情况下未调用Python

在异常情况下未调用Python,python,exception,destructor,Python,Exception,Destructor,我试图将一个写得很糟糕的Python模块(我无法控制)封装到一个类中。问题是,如果我没有显式调用该模块的close函数,那么python进程将挂起退出,因此我尝试用一个具有del方法的类包装该模块,但是在异常情况下似乎不会调用del方法 例如: class Test(object): def __init__(self): # Initialize the problematic module here print "Initializing"

我试图将一个写得很糟糕的Python模块(我无法控制)封装到一个类中。问题是,如果我没有显式调用该模块的close函数,那么python进程将挂起退出,因此我尝试用一个具有del方法的类包装该模块,但是在异常情况下似乎不会调用del方法

例如:

class Test(object):
    def __init__(self):
        # Initialize the problematic module here
        print "Initializing"

    def __del__(self):
        # Close the problematic module here
        print "Closing"

t = Test()
# This raises an exception
moo()
在这种情况下,不调用del,python挂起。当对象超出范围(如C++)时,我需要某种方式强制Python立即调用<强> del <强>。 请注意,我无法控制有问题的模块(即,无法首先修复导致此问题的错误),也无法控制使用包装类的人(无法强制他们使用“with”,因此我也无法使用退出

有什么好办法解决这个问题吗


谢谢

如果您希望在异常情况下释放某些资源,请考虑_进入_+_退出_范式

class Test(object):
    def __enter__(self):
        pass

    def __exit__(self):
        pass  # Release your resources here

with Test() as t:
    moo()

当执行进入“with”块时,调用“t”的方法uu enter uu(),然后由于正常流或异常而离开该块,调用“t”的方法u exit uu()。

一个可能的解决方案是使用,它允许您将自定义登录引入全局异常处理程序。您可以在此处添加一些代码以关闭模块的剩余部分。

请查看以下详细信息:

class Test:
    def __init__(self):
        print('cons')
    
    def __del__(self):
        print('des')
如果我们在某个全局dict中添加类测试对象,并在功能完成后清除该dict。它将调用析构函数

ctx = {}
def a():
    ctx['ao'] = Test()
    raise 1/0

a()

# cons
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 3, in a
# ZeroDivisionError: integer division or modulo by zero

不要使用del。这不是C++或为析构函数构建的语言。del方法真的应该在Python3.x中消失,尽管我相信有人会找到一个有意义的用例。如果需要使用del,请注意使用上下文管理器包装它的基本限制?正如我所说,我无法控制使用该类的人。我不能强迫他们使用“with”。@harshil9968没有理由不给del打电话。它的行为是确定性的。你只需要知道它是如何工作的。但是,在这个问题的上下文中,它不会像预期的那样工作:)请注意我的最后一部分评论-我无法控制使用包装类的人或如何使用它,也就是说,我不能强迫他们使用“with”。任何解决方案都必须仅在包装类代码内实现。好的,但是您可以控制使用该类的代码吗?您可以在该客户端代码中使用uuu enter uuuu/uuuu exit uuu。我放了一个测试类来说明这个想法。还有其他实现进入/退出功能的方法,例如使用@contextlib.contextmanger.Hi,我对使用该类的代码没有任何控制权。
\uuuuuuuuuuuuuuuuuuuuu
具有更长的签名,而不仅仅是
self
ctx  = {}
# des