On Mon, 9 May 2011, Eli Bendersky wrote: > It's a known Python gotcha (*) that the following code: > > x = 5 > def foo(): > print(x) > x = 1 > print(x) > foo() > > Will throw: > > UnboundLocalError: local variable 'x' referenced before assignment > > On the usage of 'x' 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. > > 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 'x = 1` > and marks 'x' as local in foo. Then, the code generator generates LOAD_FAST > for all loads of 'x' in 'foo', even though 'x' is actually bound locally > after the first print. When the bytecode is run, since it's LOAD_FAST and no > store was made into the local 'x', ceval.c then throws the exception. > > On first sight, it's possible to signal that 'x' truly becomes local only > after it'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 "x is > local in this block", but rather should attach scope information to each > instance of "x". This has some overhead, but it's only at the compilation > stage so it shouldn't have a real effect on the runtime of Python code. This > is also less convenient and "clean" than the current approach - this is why > I'm wondering whether the behavior is an artifact of the implementation. x = 5 def foo (): print (x) if bar (): x = 1 print (x) Isaac Morland CSCF Web Guru DC 2554C, x36650 WWW Software Specialist
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4