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