Best way to deal with default params in Python?
<p>I've got some code (that someone else wrote):</p>

<pre><code>def render(self, name, value, attrs=None):
    if not attrs:
        attrs = {}
    attrs.update({'class': 'ui-autocomplete-input'})
</code></pre>

<p>which I think could be re-written as:</p>

<pre><code>def render(self, name, value, attrs={}):
    attrs.update({'class': 'ui-autocomplete-input'})
</code></pre>

<p>This would of course fail if someone passed in <code>attrs=None</code>, but is that something to be expected?  Is there a penalty for the <code>attrs={}</code>  (extra wasted dict creation?)</p>

<p>I'm still too new to python to answer these questions, but I am curious.</p>

<p>When I test this in the interpreter, I get:</p>

<pre><code>&gt;&gt;&gt; def x(attrs={}):
...   attrs.update({'a': 'b'})
...   print attrs
... 
&gt;&gt;&gt; x({'b': 'c'})
{'a': 'b', 'b': 'c'}
&gt;&gt;&gt; x({'d': 'e'})
{'a': 'b', 'd': 'e'}
&gt;&gt;&gt; x()
{'a': 'b'}
</code></pre>

<p>How does this ever cause a problem?  Note that I'm ALWAYS adding that  dict to the attrs, even if the user specified one (which may actually point to a different problem (I should probably merge the class attribute with an existing one if present).</p>

<p>-------------------  And to point out the flaw in the above ------------------</p>

<pre><code>&gt;&gt;&gt; def yikes(attrs):
...   attrs.update({'something': 'extra'})
...   print attrs
&gt;&gt;&gt; def x(attrs={}):
...   print "Before:", attrs
...   attrs.update({'a': 'b'})
...   print "After:", attrs
...   yikes(attrs)

&gt;&gt;&gt; x({"b": "c"})
Before: {'b': 'c'}
After: {'a': 'b', 'b': 'c'}
{'a': 'b', 'b': 'c', 'something': 'extra'}
&gt;&gt;&gt; x()
Before: {}
After: {'a': 'b'}
{'a': 'b', 'something': 'extra'}
</code></pre>

<p>Still seems ok, what's the problem?</p>

<pre><code>&gt;&gt;&gt; x()
Before: {'a': 'b', 'something': 'extra'}
After: {'a': 'b', 'something': 'extra'}
{'a': 'b', 'something': 'extra'}
</code></pre>

<p>Ahhh, now I get it, if <code>{'something': 'extra'}</code> is added by some other bit of code, that never gets cleaned up.  Sure, the attrs I force to be there are there, but so is the <code>{'something': 'extra'}</code> that shouldn't be.  This is subtle enough to be good fodder for an obfuscation contest, lookout PERL!</p>
