背景:我正在使用Python编写National Instruments TestStand的COM编程。如果对象没有正确“释放”(TestStand会弹出一个“对象未正确释放”的调试对话框)。在Python中释放TestStand COM对象的方法是确保所有变量不再包含对象 - 例如。 del()
他们,或将它们设置为None
。或者,只要变量是函数局部变量,只要函数结束时变量超出范围,对象就会被释放。例外情况下的Python函数局部变量范围
嗯,我在我的程序中遵循了这个规则,只要没有例外,我的程序就会正确释放对象。但是,如果我得到一个异常,那么我得到TestStand的“对象未发布”消息。这似乎表明,当异常发生时,函数局部变量不会正常超出范围。
下面是一个简单的代码示例:
class TestObject(object):
def __init__(self, name):
self.name = name
print("Init " + self.name)
def __del__(self):
print("Del " + self.name)
def test_func(parameter):
local_variable = parameter
try:
pass
# raise Exception("Test exception")
finally:
pass
# local_variable = None
# parameter = None
outer_object = TestObject('outer_object')
try:
inner_object = TestObject('inner_object')
try:
test_func(inner_object)
finally:
inner_object = None
finally:
outer_object = None
当此运行如图所示,它显示了我的期望:
Init outer_object
Init inner_object
Del inner_object
Del outer_object
但是,如果我去掉了raise Exception...
线,而不是我得到:
Init outer_object
Init inner_object
Del outer_object
Traceback (most recent call last):
...
Exception: Test exception
Del inner_object
由于例外情况,inner_object
将被删除。
如果我取消对同时设置parameter
和local_variable
到None
行,然后我得到了我期望:
Init outer_object
Init inner_object
Del inner_object
Del outer_object
Traceback (most recent call last):
...
Exception: Test exception
所以当异常在Python中发生的,到底发生了什么起作用局部变量?他们是否被保存在某个地方,这样他们就不会像往常那样超出范围?什么是控制这种行为的“正确方法”?
谢谢。我不太清楚我的理解“您的异常处理可能通过保持对帧的引用来创建引用循环。”所以我添加了一个代码示例。我很想知道你对它的看法。 – 2010-01-14 00:07:24
@Craig,没有引用循环,但仍然比您想象的更长寿命的引用,因为只要异常处理(当您设置为()时,栈中的所有框架(以及对象的引用)没有所有这些引用,那么即使帧仍然存在,对象也可以被删除)。 – 2010-01-14 00:33:11