Unexpected python exception

Chris Rebert clp2 at rebertia.com
Wed Nov 11 07:23:18 EST 2009


On Wed, Nov 11, 2009 at 8:49 AM, Eduardo Lenz <lenz at 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



More information about the Python-list mailing list