背景:我正在使用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