Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Python

python first assignment of a global variable

 

 

Python python RSS feed   Index | Next | Previous | View Threaded


rodriguealcazar at gmail

Jul 15, 2009, 10:55 AM

Post #1 of 4 (388 views)
Permalink
python first assignment of a global variable

Hi all,

I came accross a strange behaviour in python today. Here is a simple
example to describe my situation:

MY_GLOBAL = ''

def a():
print 'global is: ', MY_GLOBAL

def b():
try:
MY_GLOBAL += 'bla'
except Exception, e:
print 'b: ', e

def c():
try:
global MY_GLOBAL
MY_GLOBAL += 'bla'
except Exception, e:
print 'c: ', e

def d():
try:
if not MY_GLOBAL:
print 'not my global'
except Exception, e:
print 'd: ', e

def e():
try:
if not MY_GLOBAL:
MY_GLOBAL = ''
except Exception, e:
print 'e: ', e

def f():
global MY_GLOBAL
if not MY_GLOBAL:
MY_GLOBAL = ''

def e_raise():
if not MY_GLOBAL:
MY_GLOBAL = 'bla'

if __name__ == "__main__":
a()
b()
c()
d()
e()
f()
e_raise()


And here is the output I get:

global is:
b: local variable 'MY_GLOBAL' referenced before assignment
e: local variable 'MY_GLOBAL' referenced before assignment
Traceback (most recent call last):
File "glo.py", line 49, in <module>
e_raise()
File "glo.py", line 39, in e_raise
if not MY_GLOBAL:
UnboundLocalError: local variable 'MY_GLOBAL' referenced before
assignment


Now, I was reading that page http://stackoverflow.com/questions/370357/python-variable-scope-question
and found (understood) only part of the behaviour that could explain
the output.

Basically, I was very surprised to discover that e() raises an
exception, but even more that e_raise() points to
if not MY_GLOBAL Is the problem not really when I assign?

My assumption is that some reordering is happening behind the scenes
that creates a situation similar to the += which assigns hence expects
to be at the local level.

I would love some enlightenment here

Rodrigue
--
http://mail.python.org/mailman/listinfo/python-list


emile at fenx

Jul 15, 2009, 11:14 AM

Post #2 of 4 (348 views)
Permalink
Re: python first assignment of a global variable [In reply to]

On 7/15/2009 10:55 AM Rodrigue said...
> I came accross a strange behaviour in python today. Here is a simple
> example to describe my situation:
>
> MY_GLOBAL = ''

<snip>

> def e_raise():
> if not MY_GLOBAL:
> MY_GLOBAL = 'bla'
>

<snip>

> Traceback (most recent call last):
> File "glo.py", line 49, in <module>
> e_raise()
> File "glo.py", line 39, in e_raise
> if not MY_GLOBAL:
> UnboundLocalError: local variable 'MY_GLOBAL' referenced before
> assignment

the def prepares the function for subsequent use. At this prep time,
MY_GLOBAL, by virtue of being assigned to later in the function, and the
absence of a global statement, is identified as a local variable.
Later, at execution time, testing MY_GLOBAL fails as it's not yet been
assigned to.

HTH,

Emile

--
http://mail.python.org/mailman/listinfo/python-list


milesck at umich

Jul 15, 2009, 11:17 AM

Post #3 of 4 (362 views)
Permalink
Re: python first assignment of a global variable [In reply to]

On Jul 15, 2009, at 1:55 PM, Rodrigue wrote:

> Basically, I was very surprised to discover that e() raises an
> exception, but even more that e_raise() points to
> if not MY_GLOBAL Is the problem not really when I assign?
>
> My assumption is that some reordering is happening behind the scenes
> that creates a situation similar to the += which assigns hence expects
> to be at the local level.

The determination of whether a name is a reference to a local or
global variable is made at compile time. When a function contains a
single assignment (or augmented assignment) to a name, the compiler
generates bytecode such that all references to that name within the
function will be looked up in the local scope only, including those
before the assignment statement.

-Miles

--
http://mail.python.org/mailman/listinfo/python-list


rodriguealcazar at gmail

Jul 15, 2009, 1:27 PM

Post #4 of 4 (346 views)
Permalink
Re: python first assignment of a global variable [In reply to]

> MY_GLOBAL, by virtue of being assigned to later in the function, and the
> absence of a global statement, is identified as a local variable.

> When a function contains a
> single assignment (or augmented assignment) to a name, the compiler
> generates bytecode such that all references to that name within the
> function will be looked up in the local scope only

Alright. I didn't know that. I thought the entire scope (local, then
global) was considered in every situation. It does explain the
observed behaviour then.

I'm surprised I never bumped into that before, but I'm glad I learnt
something new about python today.

Thanks Emile and Miles for the explanation!
--
http://mail.python.org/mailman/listinfo/python-list

Python python RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.