Wenn Sie eine Ausnahme mit Python (CPython) auslösen, wird der Frame, der die Ausnahme ausgelöst hat, dem Frame hinzugefügt, der die Ausnahme abgefangen hat. Dies macht das Verhalten des Referenzzählers nicht trivial und verlängert unbeabsichtigt die Lebensdauer des Objekts.
class Foo(Exception):
def __init__(self):
print 'construt'
def __del__(self):
print 'destruct'
def raiseError(self):
raise Exception()
def main ():
print 'enter main'
foo = Foo()
try:
foo.raiseError()
except:
print 'catch exception'
foo = None
print 'exit main'
try:
main()
finally:
print 'finish'
Die Ausgabe des obigen Codes ist wie folgt.
enter main
construt
catch exception
exit main
destruct
finish
Wie oben erwähnt, verlängert sich die Lebensdauer von "foo", bis der Rahmen von "main" freigegeben wird, selbst wenn das "foo" -Objekt in "main" vor "exit main" freigegeben werden soll.
Dies liegt daran, dass der Frame innerhalb des raiseError
, der die Ausnahme ausgelöst hat, im Frame innerhalb des main
gehalten wird und der Frame innerhalb des liftError`` self = foo
enthält.
Ausnahmerahmen werden mit sys.exc_clear ()
freigegeben.
In einem ähnlichen Fall kann beim Versuch, in einer Schleife zu fangen, der Freigabezeitpunkt des in der Schleife gesicherten Objekts um eine Schleife verschoben werden. Dies liegt daran, dass der Ausnahmerahmen durch den Ausnahmewurf in der nächsten Schleife freigegeben wird.
http://stackoverflow.com/questions/8822418/object-not-freed-after-an-exception-raise-in-python-2-7
Recommended Posts