<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Caching Dictionaries in Python vs. Ruby</title>
	<atom:link href="http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/feed" rel="self" type="application/rss+xml" />
	<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby</link>
	<description>A traveling geek&#039;s blog on development, games, and the web</description>
	<lastBuildDate>Tue, 17 Jan 2012 16:49:00 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Peter Harkins</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87377</link>
		<dc:creator>Peter Harkins</dc:creator>
		<pubDate>Tue, 05 Feb 2008 01:34:24 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87377</guid>
		<description>Justin: You&#039;re correct there. I simplified from my examples that passed keyword and other arguments to &lt;kbd&gt;expensive_operation&lt;/kbd&gt;.

Doug: It sounds like your criticism is that the LambdaDict can&#039;t cache things the builtin Dict it&#039;s based can&#039;t cache. I&#039;m OK with that limitation. I agree that injection is a great way to shoot yourself in the foot, that&#039;s why I talked about it as garnish rather than a side dish. I&#039;ve avoided the pitfalls, though I admit that&#039;s at least partially luck.

Philip: Defaultdict doesn&#039;t work here, it can&#039;t pass arguments or do the other things that Justin noticed I elided from my example.

Dave: Great, got a link? I spent a while searching for code before writing my dict, but I didn&#039;t think to search for &quot;memoize&quot; (obvious now that you&#039;ve said it).

(Thanks for the great comments, folks. I&#039;ve add &lt;code lang=&quot;python&quot;&gt;...&lt;code&gt; where needed.)</description>
		<content:encoded><![CDATA[<p>Justin: You&#8217;re correct there. I simplified from my examples that passed keyword and other arguments to <kbd>expensive_operation</kbd>.</p>
<p>Doug: It sounds like your criticism is that the LambdaDict can&#8217;t cache things the builtin Dict it&#8217;s based can&#8217;t cache. I&#8217;m OK with that limitation. I agree that injection is a great way to shoot yourself in the foot, that&#8217;s why I talked about it as garnish rather than a side dish. I&#8217;ve avoided the pitfalls, though I admit that&#8217;s at least partially luck.</p>
<p>Philip: Defaultdict doesn&#8217;t work here, it can&#8217;t pass arguments or do the other things that Justin noticed I elided from my example.</p>
<p>Dave: Great, got a link? I spent a while searching for code before writing my dict, but I didn&#8217;t think to search for &#8220;memoize&#8221; (obvious now that you&#8217;ve said it).</p>
<p>(Thanks for the great comments, folks. I&#8217;ve add &lt;code lang=&#8221;python&#8221;&gt;&#8230;&lt;code&gt; where needed.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87373</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Mon, 04 Feb 2008 16:57:49 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87373</guid>
		<description>The setdefault will not work, since the arguments are evaluated before the call to setdefault.  So expensive_calculation will always be called, even if the result is already in the dictionary.

The pythonic solution is to write a memoizing decorator - or use one of the many already in the ASPN Python Cookbook. 
Then you can do 

&lt;code lang=&quot;python&quot;&gt;
@memoize
def expensive_calculation(...):
    ....
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>The setdefault will not work, since the arguments are evaluated before the call to setdefault.  So expensive_calculation will always be called, even if the result is already in the dictionary.</p>
<p>The pythonic solution is to write a memoizing decorator &#8211; or use one of the many already in the ASPN Python Cookbook.<br />
Then you can do </p>
<pre>&nbsp;
@memoize
<span style="color: #b1b100;">def</span> expensive_calculation<span style="color: #66cc66;">&#40;</span>...<span style="color: #66cc66;">&#41;</span>:
    ....</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dan</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87370</link>
		<dc:creator>Dan</dc:creator>
		<pubDate>Mon, 04 Feb 2008 14:10:36 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87370</guid>
		<description>@philip: How would you do this with defaultdict? AIUI defaultdict lets you specify a default, but doesn&#039;t do any kind of caching - in fact, it doesn&#039;t even let you specify the default as a function of the key.

@david: I like that solution.</description>
		<content:encoded><![CDATA[<p>@philip: How would you do this with defaultdict? AIUI defaultdict lets you specify a default, but doesn&#8217;t do any kind of caching &#8211; in fact, it doesn&#8217;t even let you specify the default as a function of the key.</p>
<p>@david: I like that solution.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Avraamides</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87355</link>
		<dc:creator>David Avraamides</dc:creator>
		<pubDate>Sat, 02 Feb 2008 23:39:44 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87355</guid>
		<description>Why not:

&lt;code lang=&quot;python&quot;&gt;
results = {}
 
for item in really_big_list:
    result = results.setdefault(key, expensive_calculation(key))
    # â€¦ do something useful with item and result
&lt;/code&gt;

Then you don&#039;t need a custom class.</description>
		<content:encoded><![CDATA[<p>Why not:</p>
<pre>&nbsp;
results = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>

<span style="color: #b1b100;">for</span> item <span style="color: #b1b100;">in</span> really_big_list:
    result = results.<span style="color: #202020;">setdefault</span><span style="color: #66cc66;">&#40;</span>key, expensive_calculation<span style="color: #66cc66;">&#40;</span>key<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># &acirc;€&brvbar; do something useful with item and result</span></pre>
<p>Then you don&#8217;t need a custom class.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Philip Jenvey</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87354</link>
		<dc:creator>Philip Jenvey</dc:creator>
		<pubDate>Sat, 02 Feb 2008 22:26:14 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87354</guid>
		<description>Python 2.5 already includes collections.defaultdict which is exactly what you&#039;re looking for.

Open classes are an entirely different issue. It can be really handy when tinkering around with things. Though, like Doug points out, when it comes to a large application with many libraries, all maintained by multiple developers, it becomes an easy way to shoot yourself in the foot</description>
		<content:encoded><![CDATA[<p>Python 2.5 already includes collections.defaultdict which is exactly what you&#8217;re looking for.</p>
<p>Open classes are an entirely different issue. It can be really handy when tinkering around with things. Though, like Doug points out, when it comes to a large application with many libraries, all maintained by multiple developers, it becomes an easy way to shoot yourself in the foot</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Doug Napoleone</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87353</link>
		<dc:creator>Doug Napoleone</dc:creator>
		<pubDate>Sat, 02 Feb 2008 21:14:26 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87353</guid>
		<description>I think one of the reasons why Python does not have a default way of doing this is because there are many &#039;correct&#039; ways to do it depending on the problem you are trying to solve.

For instance, your implementation has some issues. It will not work if your attribute is a dictionary as dictionaries are not hashable and can&#039;t be used as keys. If it is a complex object, the hash will be on the instance id (pointer) verses the data it contains unless you override __hash__. I have seen a number of examples of caching using decorators and descriptors (I often use a descriptor decorator to do dynamic caching of attributes).

I have used ruby extensively and run into similar issues with using the builtin  caching behavior. In the end, most of the time I had to write my own (as I rarely deal with simple things). 

In the end, ruby has some native helpers for the most common use cases, but it is easy enough to write generic python decorators or descriptors to do the same thing in python. 

As for monkey patching... Well one of the things I hate about Ruby is injection. It has cost the company I work for hundreds of hours of grief. The real problem are the people using the language all injecting their crap without regard to what other people are doing, but that is what researchers do. And I hate it in python even more (as ruby gives you some protection from bad things where python gives you none).

yes its cool, yes it allows you to do some very powerful things... but it is a bad thing to do in a large codebase with multiple people who don&#039;t talk to each other about every change they make (which is 90% of &#039;professional&#039; software development.) As one researcher said after a week of debugging, &#039;That is some beautiful rope we hung ourselves with.&#039;</description>
		<content:encoded><![CDATA[<p>I think one of the reasons why Python does not have a default way of doing this is because there are many &#8216;correct&#8217; ways to do it depending on the problem you are trying to solve.</p>
<p>For instance, your implementation has some issues. It will not work if your attribute is a dictionary as dictionaries are not hashable and can&#8217;t be used as keys. If it is a complex object, the hash will be on the instance id (pointer) verses the data it contains unless you override __hash__. I have seen a number of examples of caching using decorators and descriptors (I often use a descriptor decorator to do dynamic caching of attributes).</p>
<p>I have used ruby extensively and run into similar issues with using the builtin  caching behavior. In the end, most of the time I had to write my own (as I rarely deal with simple things). </p>
<p>In the end, ruby has some native helpers for the most common use cases, but it is easy enough to write generic python decorators or descriptors to do the same thing in python. </p>
<p>As for monkey patching&#8230; Well one of the things I hate about Ruby is injection. It has cost the company I work for hundreds of hours of grief. The real problem are the people using the language all injecting their crap without regard to what other people are doing, but that is what researchers do. And I hate it in python even more (as ruby gives you some protection from bad things where python gives you none).</p>
<p>yes its cool, yes it allows you to do some very powerful things&#8230; but it is a bad thing to do in a large codebase with multiple people who don&#8217;t talk to each other about every change they make (which is 90% of &#8216;professional&#8217; software development.) As one researcher said after a week of debugging, &#8216;That is some beautiful rope we hung ourselves with.&#8217;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin Teague</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87352</link>
		<dc:creator>Kevin Teague</dc:creator>
		<pubDate>Sat, 02 Feb 2008 19:55:33 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87352</guid>
		<description>Yes, some of us have seen open classes in Python. For example, Plone&#039;s Archetypes takes a schema declaration and dynamically generates methods on a class based on that information, similar to much of the class re-opening stuff that goes on in ActiveRecord. We have even seen open classes before Rails since development of Archetypes goes back to 2002 :)

http://plone.tv/media/430268733

Note that in the Zope world where the term monkey patch originated from, the dynamic class modifications of Archetypes is *not* called monkey patching. Monkey patching only applies where your reason for re-opening a class is in order to patch it to fix bugs or mis-features similar to traditional software patches:

http://www.catb.org/esr/jargon/html/P/patch.html</description>
		<content:encoded><![CDATA[<p>Yes, some of us have seen open classes in Python. For example, Plone&#8217;s Archetypes takes a schema declaration and dynamically generates methods on a class based on that information, similar to much of the class re-opening stuff that goes on in ActiveRecord. We have even seen open classes before Rails since development of Archetypes goes back to 2002 :)</p>
<p><a href="http://plone.tv/media/430268733" rel="nofollow">http://plone.tv/media/430268733</a></p>
<p>Note that in the Zope world where the term monkey patch originated from, the dynamic class modifications of Archetypes is *not* called monkey patching. Monkey patching only applies where your reason for re-opening a class is in order to patch it to fix bugs or mis-features similar to traditional software patches:</p>
<p><a href="http://www.catb.org/esr/jargon/html/P/patch.html" rel="nofollow">http://www.catb.org/esr/jargon/html/P/patch.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Justin</title>
		<link>http://push.cx/2008/caching-dictionaries-in-python-vs-ruby/comment-page-1#comment-87351</link>
		<dc:creator>Justin</dc:creator>
		<pubDate>Sat, 02 Feb 2008 19:17:05 +0000</pubDate>
		<guid isPermaLink="false">http://push.cx/2008/caching-dictionaries-in-python-vs-ruby#comment-87351</guid>
		<description>&lt;code lang=&quot;python&quot;&gt;results = LambdaDict(expensive_calculation)&lt;/code&gt; ?</description>
		<content:encoded><![CDATA[<pre>results = LambdaDict<span style="color: #66cc66;">&#40;</span>expensive_calculation<span style="color: #66cc66;">&#41;</span></pre>
<p> ?</p>
]]></content:encoded>
	</item>
</channel>
</rss>

