By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,168 Members | 1,171 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,168 IT Pros & Developers. It's quick & easy.

Problem with global variables

P: n/a
I'm having a vexing problem with global variables in Python. Please
consider the following Python code:

#! /usr/bin/env python

def tiny():
bar = []
for tmp in foo:
bar.append(tmp)
foo = bar

if __name__ == "__main__":
foo = ['hello', 'world']
tiny()

When I try to run this, I get:

Traceback (most recent call last):
File "./xtalk.py", line 11, in ?
tiny()
File "./xtalk.py", line 5, in tiny
for tmp in foo:
UnboundLocalError: local variable 'foo' referenced before assignment

For some reason, Python can't see the global variable "foo" in the
function tiny(). Why is that?

If I change the code to this:

#! /usr/bin/env python

def tiny():
for tmp in foo:
print tmp

if __name__ == "__main__":
foo = ['hello', 'world']
tiny()

I get this:

hello
world

All of a sudden, tiny() can see the global variable "foo". Very
confusing! Why is it that tiny() sometimes can, and sometimes can't,
see the global variable "foo"?

If anyone can enlighten me about what's going on with Python and
global variables, I would appreciate it!
Apr 2 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
hg
Ed Jensen wrote:
#! /usr/bin/env python

def tiny():
bar = []
for tmp in foo:
bar.append(tmp)
foo = bar

if __name__ == "__main__":
foo = ['hello', 'world']
tiny()

Like this ?

#! /usr/bin/env python

def tiny():
* * bar = []
gobal foo
* * for tmp in foo:
* * * * bar.append(tmp)
* * foo = bar

if __name__ == "__main__":
* * foo = ['hello', 'world']
* * tiny()
hg

Apr 2 '07 #2

P: n/a
Ed Jensen a écrit :
I'm having a vexing problem with global variables in Python. Please
consider the following Python code:

#! /usr/bin/env python

def tiny():
bar = []
for tmp in foo:
bar.append(tmp)
foo = bar

if __name__ == "__main__":
foo = ['hello', 'world']
tiny()

When I try to run this, I get:

Traceback (most recent call last):
File "./xtalk.py", line 11, in ?
tiny()
File "./xtalk.py", line 5, in tiny
for tmp in foo:
UnboundLocalError: local variable 'foo' referenced before assignment

For some reason, Python can't see the global variable "foo" in the
function tiny(). Why is that?

If I change the code to this:

#! /usr/bin/env python

def tiny():
for tmp in foo:
print tmp

if __name__ == "__main__":
foo = ['hello', 'world']
tiny()

I get this:

hello
world

All of a sudden, tiny() can see the global variable "foo". Very
confusing! Why is it that tiny() sometimes can, and sometimes can't,
see the global variable "foo"?

If anyone can enlighten me about what's going on with Python and
global variables, I would appreciate it!
To complete hg reply, Python compile your tiny function which contains a
foo assignment. As foo is not defined "global", it is considered to be
local. So the error when you tries to iterate throught foo before
assigning it. And so the solution to add "global foo" before using it.

A+

Laurent.
Apr 2 '07 #3

P: n/a
Laurent Pointal wrote:
And so the solution to add "global foo" before using it.
Didn't you read his final question?

| All of a sudden, tiny() can see the global variable "foo". Very
| confusing! Why is it that tiny() sometimes can, and sometimes
| can't, see the global variable "foo"?

I have no explanation for this, but I'm interested in one, too.

Regards,
Björn

--
BOFH excuse #422:

Someone else stole your IP address, call the Internet detectives!

Apr 2 '07 #4

P: n/a
Bjoern Schliessmann wrote:
Laurent Pointal wrote:
>And so the solution to add "global foo" before using it.

Didn't you read his final question?

| All of a sudden, tiny() can see the global variable "foo". Very
| confusing! Why is it that tiny() sometimes can, and sometimes
| can't, see the global variable "foo"?

I have no explanation for this, but I'm interested in one, too.
It doesn't happen "all of a sudden", it happens when the assignment to
foo is removed from the function definition. The interpreter therefore
no longer regards foo as a local variable.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Recent Ramblings http://holdenweb.blogspot.com

Apr 2 '07 #5

P: n/a
Bjoern Schliessmann schreef:
Laurent Pointal wrote:
>And so the solution to add "global foo" before using it.

Didn't you read his final question?

| All of a sudden, tiny() can see the global variable "foo". Very
| confusing! Why is it that tiny() sometimes can, and sometimes
| can't, see the global variable "foo"?

I have no explanation for this, but I'm interested in one, too.
Within functions Python can read from global variables, even without a
'global' statement. Complications only arise when you try to write to
it: in that case Python assumes it is a local variable instead of a global.

It surprised me a bit when I first found out about this: I would have
thought that Python would threat it as a local throughout the function
until the function assigns something to it. That's not what happens: if
the function assigns to it, *all* mentions of the variable are
considered local.

--
If I have been able to see further, it was only because I stood
on the shoulders of giants. -- Isaac Newton

Roel Schroeven
Apr 2 '07 #6

P: n/a
On Apr 2, 5:29 pm, Bjoern Schliessmann <usenet-
mail-0306.20.chr0n...@spamgourmet.comwrote:
Laurent Pointal wrote:
And so the solution to add "global foo" before using it.

Didn't you read his final question?

| All of a sudden, tiny() can see the global variable "foo". Very
| confusing! Why is it that tiny() sometimes can, and sometimes
| can't, see the global variable "foo"?

I have no explanation for this, but I'm interested in one, too.

Regards,

Björn
Laurent Pointal did explain this. "foo" is considered to be a local
variable (scope limited to the function) if it's being assigned to in
a function and there's no "global foo" statement. So even the "foo"
before the actual assignment will refer to the local variable. But the
local variable hasn't been assigned yet at that point and an exception
is thrown. Yes, one could have a perfectly working function, then add
an innocent-looking assignment statement at the very end of the
function, and suddenly you'd get an exception thrown at the beginning
of the function where that variable is used - Far away from the place
where the modification was made.

Why does it work like this? Couldn't it be somehow more uniform or
less surprising?

Well, if one had to define "global foo" even when one were to just
read the variable foo, that'd be a pain in the ass. You'd have to use
"global math" to use math module in a function and "global
anotherFunction" to call anotherFunction, and so on. There's plenty of
stuff in the global scope that you don't normally assign to.

Another option would be to scrap "global" keyword and let "foo = bar"
do an assignment to the global variable if a global variable named
"foo" exists, but create (or assign) to a function local variable if
it doesn't exist. That'd work but programming would be horrible. Now
you'd have to know all the symbols that exist at the global scope,
because if you accidentally accessed a global variable instead of
local, your function would probably have undesirable side-effects.

Now, name clashes could be solved with a naming convention (which
could be enforced at the language level). It could be possible that
all accesses to global scope would have to be prefixed by some symbol
like $. E.g. "$foo = 4; foo = 6" where former assigns to global foo,
latter to local foo. That's one option that might work and be somewhat
readable.. But not a good tradeoff IMO, considering how rarely global
assignment is needed and how often global variables are read.

A remaining option is to use different operator for assignment and
initialization. So you'd have to do e.g. "a := 4; a = 7". I'm not sure
Pythonistas would prefer this either, although many other languages
choose this route (through lets or declarations typically).

Apr 2 '07 #7

P: n/a
Ed Jensen <ej*****@visi.comwrote:
I'm having a vexing problem with global variables in Python.
<SNIP>

Thanks to everyone who replied. The peculiar way Python handles
global variables in functions now makes sense to me.
Apr 2 '07 #8

P: n/a
Bjoern Schliessmann wrote:
Laurent Pointal wrote:
>And so the solution to add "global foo" before using it.

Didn't you read his final question?
Yes, and i replies: "which contains a foo assignment. As foo is not
defined "global", it is considered to be local. "

Maybe my explanation was not clear enough with variable foo to be considered
local because there is an *assignment* to foo.

A+

Laurent.
Apr 2 '07 #9

P: n/a
Laurent Pointal wrote:
Yes, and i replies: "which contains a foo assignment. As foo is
not defined "global", it is considered to be local. "

Maybe my explanation was not clear enough with variable foo to be
considered local because there is an *assignment* to foo.
Yep, thanks for the clarification. After four replies and despite
weird conjugations, I've definitely got it now ... ;)

Regards,
Björn

--
BOFH excuse #113:

Root nameservers are out of sync

Apr 2 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.