On Wed, Nov 11, 2009 at 8:49 AM, Eduardo Lenz <l...@joinville.udesc.br> wrote: > Em Qua 11 Nov 2009, às 03:21:55, Diez B. Roggisch escreveu: >> Richard Purdie schrieb: >> > I've been having problems with an unexpected exception from python which >> > I can summarise with the following testcase: >> > >> > def A(): >> > import __builtin__ >> > import os >> > >> > __builtin__.os = os >> > >> > def B(): >> > os.stat("/") >> > import os >> > >> > A() >> > B() >> > >> > which results in: >> > >> > Traceback (most recent call last): >> > File "./test.py", line 12, in <module> >> > B() >> > File "./test.py", line 8, in B >> > os.stat("/") >> > UnboundLocalError: local variable 'os' referenced before assignment >> > >> > If I remove the "import os" from B(), it works as expected. >> > >> >>From what I've seen, its very unusual to have something operate >> > >> > "backwards" in scope in python. Can anyone explain why this happens? >> >> As the import-statement in a function/method-scope doesn't leak the >> imported names into the module scope, python treats them as locals. >> Which makes your code equivalent to >> >> >> x = 1000 >> >> def foo(): >> print x >> x = 10 >> >> Throws the same error. The remedy is to inform python that a specific >> name belongs to global scope, using the "global"-statement. >> >> def foo(): >> global x >> print x >> x = 10 >> >> >> Beware though that then of course *assigning* to x is on global level. >> This shouldn't be of any difference in your case though, because of the >> import-only-once-mechanics of python. >> >> Diez >> > > So...it should not work > > def A(): > import __builtin__ > import os > __builtin__.os = os > > A() > os.stat("/") > > but it does. Why ? B() cannot see the import, but the global level can ?
The optimization which results in the behavior in question is only done on functions scopes, not global scope. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list