<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Algorithm Blogs &#187; gotchas</title>
	<atom:link href="http://www.algorithm.co.il/blogs/index.php/category/programming/gotchas/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.algorithm.co.il/blogs</link>
	<description>Algorithms, for the heck of it</description>
	<lastBuildDate>Thu, 22 Apr 2010 21:04:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Python Gotchas 1: __del__ is not the opposite of __init__</title>
		<link>http://www.algorithm.co.il/blogs/index.php/programming/python/python-gotchas-1-__del__-is-not-the-opposite-of-__init__/</link>
		<comments>http://www.algorithm.co.il/blogs/index.php/programming/python/python-gotchas-1-__del__-is-not-the-opposite-of-__init__/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 07:18:17 +0000</pubDate>
		<dc:creator>lorg</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[gotchas]]></category>
		<category><![CDATA[Gotcha]]></category>
		<category><![CDATA[__del__]]></category>

		<guid isPermaLink="false">http://www.algorithm.co.il/blogs/?p=438</guid>
		<description><![CDATA[After discussing my last post with a friend and talking about a few other issues, we came to the conclusion that it would be worthwhile to discuss more gotchas.
First though, what is a gotcha? Wikipedia gives a good definition:
In programming, a gotcha is a feature of a system, a program or a programming language that [...]]]></description>
			<content:encoded><![CDATA[<p>After discussing my <a href="http://www.algorithm.co.il/blogs/index.php/programming/python/generatorexit-another-reason-to-upgrade-to-python-2-6/">last post</a> with a friend and talking about a few other issues, we came to the conclusion that it would be worthwhile to discuss more gotchas.</p>
<p>First though, what is a gotcha? Wikipedia gives a <a href="http://en.wikipedia.org/wiki/Gotcha_%28programming%29">good definition</a>:</p>
<blockquote><p>In programming, a gotcha is a feature of a system, a program or a programming language that works in the way it is documented but is counter-intuitive and almost invites mistakes because it is both enticingly easy to invoke and completely unexpected and/or unreasonable in its outcome.</p></blockquote>
<p>So let's start with "__del__ is not the opposite of __init__".<br />
If you come from c++ or a similar background, you are probably well versed in object oriented concepts, specifically, constructors and destructors. The usual expectation is to have the destructor called only for fully constructed objects - i.e., objects whose constructor returned without raising an exception.</p>
<p>If the constructor raises an exception, it is expected to "clean up after itself", and not expect the destructor to run.</p>
<p>Since in Python __init__ is the de-facto constructor, and __del__ is considered the destructor, most people expect this line of reasoning to work with __init__ and __del__.<br />
This is mistaken. __del__ is not the opposite of __init__, but rather of __new__. Which means that if __init__ raises an exception, then __del__ will still be called.<br />
I've run into this issue myself several times in the past. Consider the following sample code:</p>
<div class="syntax_hilite">
<div id="python-3">
<div class="python"><span style="color: #00007f;font-weight:bold;">class</span> A<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>,x<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">if</span> x == <span style="color: #ff4500;">0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: #000000;">x</span> = x<br />
&nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">def</span> <span style="color: #0000cd;">__del__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f;font-weight:bold;">print</span> <span style="color: #008000;">self</span>.<span style="color: #000000;">x</span></div>
</div>
</div>
<p></p>
<p>This code demonstrates a common case: a constructor that might fail, and a destructor that does something with the instance's members. If you try to instantiate A with x = 0, you'll get an exception. This is to be expected.<br />
However, what is less expected is when the partially constructed A is garbage-collected (which may be anytime later, and not necessarily right away):</p>
<div class="syntax_hilite">
<div id="python-4">
<div class="python"><span style="color: #008000;">Exception</span> <span style="color: #dc143c;">exceptions</span>.<span style="color: #008000;">AttributeError</span>: <span style="color: #483d8b;">"'A' object has no attribute 'x'"</span> <span style="color: #00007f;font-weight:bold;">in</span> &lt;bound<br />
&nbsp;method A.<span style="color: #0000cd;">__del__</span> of &lt;__main__.<span style="color: #000000;">A</span> <span style="color: #008000;">object</span> at 0x02449570&gt;&gt; ignored</div>
</div>
</div>
<p></p>
<p>What happened is that __del__ was called even though __init__ raised an exception. When __del__ tried to access self.x it got an attribute error, because it hasn't been defined yet.</p>
<p>The solution?<br />
1. Don't use __del__ unless you really have to. I'm going to write a more about it soon.<br />
2. If you do use __del__ make sure you are covered for any case in which __init__ didn't finish running. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.algorithm.co.il/blogs/index.php/programming/python/python-gotchas-1-__del__-is-not-the-opposite-of-__init__/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
