variable scoping problem

Tung Wai Yip tungwaiyip at yahoo.com
Fri Apr 25 19:56:10 CEST 2003


On 25 Apr 2003 02:15:57 +0100, Alexander Schmolck <a.schmolck at gmx.net>
wrote:

>Tung Wai Yip <tungwaiyip at yahoo.com> writes:
>
>> Consider this
>> 
>> >>> x=1
>> >>> def foo():
>> ...   print x
>> ...
>> >>> def bar():
>> ...   #print x   <- referenced before assignment error
>> ...   x=2
>> ...   print x
>> ...
>> >>> foo()
>> 1
>> >>> bar()
>> 2
>> >>> print x
>> 1
>> >>>
>> 
>> What rules in Python explain the scoping of x? Is there a name for the
>> scope of the first x? 'module' scope? Why is bar() not able to access
>> x but foo() can?
>
>Q1: global scope
>
>Q2: Because when python sees that x is assigned to in a function it is treated
>as a local variable *anywhere* in that function (even *before* the
>assignment); *unless* you've declared it as global in that function. As long
>as you don't assign to it, you're fine.
>
>This makes sense -- otherwise you could easily introduce devious bugs by
>changing global variables without any intent of doing so. OTOH, you don't want
>to have to declare a module, function or a constant global just so that you
>can use it from within the function.
>
>Consider (all untested):
>
>def aTest():
>    print "HI"
>
>def bTest():
>    def aTest(): print "Just a local definition"
>    aTest()
>
>then consider:
>
>>>> aTest
>HI
>>>> bTest()
>Just a local definition
>>>> aTest()
>HI
>
>def aTest():
>    print "HI"
>
>def bTest():
>    aTest() 
>    def aTest(): print "NEVER"
>    return aTest(3)
>>>> bTest()
>
>
>and finally:
>
>def aTest():
>    print "HI"
>def bTest():
>    global aTest
>    aTest()
>    def aTest(): print "REDEFINED GLOBALLY"
>    aTest()
>>>> aTest()
>Hi
>>>> bTest()
>HI
>REDEFINED GLOBALLY
>>>> aTest()
>REDEFINED GLOBALLY
>
>
>'as

Bingo. The 'global' keyword solved my problem. All I'm trying to do is
to have a global variable to shared value so that one function can
read the value saved by a previous function.

For people with C background Python's way is rather different. It
threats a name differently when it is used for read only versus it is
written to. I understand your example. But I'm not sure which problem
is worst, to threat a name differently depends on usage or to
unintentional overwritten a global variable. C's way has its problem
but at least I'm very used to it. The most unambigous way is to force
people to declare variable first (but I guess this would be unpythonic
:).





More information about the Python-list mailing list