More Warts in Python Exceptions
I’ve previously blogged about a little Python wart in the way exceptions differ from the way it’s raised.
Here’s another one that may surprise you, especially if you are writing long running processes like servers. But I have a real love/hate relationship with it. On one hand, the behavior makes Python really sweet to work with, on the other it can really trip people up.
Have a look and see what you think will happen here, and then tell me what do you prefer? Easy debuggability or surprising behavior?
class A:
def __init__(self):
print "Initialized %r" % self
def __del__(self):
print "Finalized %r" % self
def foo():
a = A()
raise Exception
try:
foo()
except:
pass
raw_input("Press enter to continue:")
The surprising result is that the instance of A is not finalized when it goes out of scope:
Initialized <__main__.A instance at 0x00B86B20>
Press enter to continue: Press enter
Finalized <__main__.A instance at 0x00B86B20>
Reason: When an exception is thrown, python stores every stackframe (including local variables) in the traceback. This means that the stackframe holding a reference to the A instance has not been destroyed yet, as it’s still available for debuggers to inspect. Finalization occurs only when another exception is thrown.
If a contains open file handles that gets closed when finalized, you end up with mystery processes that’s locking your file.
About this entry
You’re currently reading “ More Warts in Python Exceptions ,” an entry on Chui's Counterpoint
- Published:
- 5.17.07 / 9am
- Category:
- Python
11 Comments
Jump to comment form | comments rss [?] | trackback uri [?]