<p>On May 9, 2011 6:59 AM, &quot;Eli Bendersky&quot; &lt;<a href="mailto:eliben@gmail.com">eliben@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; Hi all,<br>
&gt;<br>
&gt; It&#39;s a known Python gotcha (*) that the following code:<br>
&gt;<br>
&gt; x = 5<br>
&gt; def foo():<br>
&gt;     print(x)<br>
&gt;     x = 1<br>
&gt;     print(x)<br>
&gt; foo()<br>
&gt;<br>
&gt; Will throw:<br>
&gt;<br>
&gt;        UnboundLocalError: local variable &#39;x&#39; referenced before assignment<br>
&gt;<br>
&gt; On the usage of &#39;x&#39; in the *first* print. Recently, while reading the zillionth question on StackOverflow on some variation of this case, I started thinking whether this behavior is desired or just an implementation artifact. <br>

&gt;<br>
&gt; IIUC, the reason it behaves this way is that the symbol table logic goes over the code before the code generation runs, sees the assignment &#39;x = 1` and marks &#39;x&#39; as local in foo. Then, the code generator generates LOAD_FAST for all loads of  &#39;x&#39; in &#39;foo&#39;, even though &#39;x&#39; is actually bound locally after the first print. When the bytecode is run, since it&#39;s LOAD_FAST and no store was made into the local &#39;x&#39;, ceval.c then throws the exception.<br>

&gt;<br>
&gt; On first sight, it&#39;s possible to signal that &#39;x&#39; truly becomes local only after it&#39;s bound in the scope (and before that LOAD_NAME can be generated for it instead of LOAD_FAST). To do this, some modifications to the symbol table creation and usage are required, because we can no longer say &quot;x is local in this block&quot;, but rather should attach scope information to each instance of &quot;x&quot;. This has some overhead, but it&#39;s only at the compilation stage so it shouldn&#39;t have a real effect on the runtime of Python code. This is also less convenient and &quot;clean&quot; than the current approach - this is why I&#39;m wondering whether the behavior is an artifact of the implementation.<br>

&gt;<br>
&gt; Would it not be worth to make Python&#39;s behavior more expected in this case, at the cost of some implementation complexity? What are the cons to making such a change? At least judging by the amount of people getting confused by it, maybe it&#39;s in line with the zen of Python to behave more explicitly here.</p>

<p>This is about mixing scopes for the the same name in the same block, right?  Perhaps a more specific error would be enough, unless there is a good use case for having that mixed scope for the name.</p>
<p>-eric</p>
<p>&gt; Thanks in advance,<br>
&gt; Eli<br>
&gt;<br>
&gt; (*) Variation of this FAQ: <a href="http://docs.python.org/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value">http://docs.python.org/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value</a><br>

&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Python-Dev mailing list<br>
&gt; <a href="mailto:Python-Dev@python.org">Python-Dev@python.org</a><br>
&gt; <a href="http://mail.python.org/mailman/listinfo/python-dev">http://mail.python.org/mailman/listinfo/python-dev</a><br>
&gt; Unsubscribe: <a href="http://mail.python.org/mailman/options/python-dev/ericsnowcurrently%40gmail.com">http://mail.python.org/mailman/options/python-dev/ericsnowcurrently%40gmail.com</a><br>
&gt;<br>
</p>