Problem with global variables

2007-04-02 Thread Ed Jensen
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!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Problem with global variables

2007-04-02 Thread 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

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


Re: Problem with global variables

2007-04-02 Thread Laurent Pointal
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.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Problem with global variables

2007-04-02 Thread Bjoern Schliessmann
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!

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


Re: Problem with global variables

2007-04-02 Thread Steve Holden
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

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


Re: Problem with global variables

2007-04-02 Thread Roel Schroeven
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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Problem with global variables

2007-04-02 Thread irstas
On Apr 2, 5:29 pm, 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.
>
> 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).

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


Re: Problem with global variables

2007-04-02 Thread Ed Jensen
Ed Jensen <[EMAIL PROTECTED]> wrote:
> I'm having a vexing problem with global variables in Python.



Thanks to everyone who replied.  The peculiar way Python handles
global variables in functions now makes sense to me.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Problem with global variables

2007-04-02 Thread Laurent Pointal
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.


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


Re: Problem with global variables

2007-04-02 Thread Bjoern Schliessmann
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

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


problem with global variable in a module

2006-11-25 Thread hollowspook
def aa():
global b
b=b+1
print b

b=1
aa()

The above code runs well in python shell.

However I  have a problem as follows.

new a file named test.py


def aa():
global b
b=b+1
print b
-

Then in python shell,

from test import *
b=1
aa()

The error message is :
Traceback (most recent call last):
  File "", line 1, in ?
  File "test.py", line 3, in aa
b=b+1
NameError: global name 'b' is not defined

Why this happens? Please do me a favor. 
Thanks in advance

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

Re: problem with global variable in a module

2006-11-25 Thread Duncan Booth
"hollowspook" <[EMAIL PROTECTED]> wrote:

> from test import *
> b=1
> aa()
> 
> The error message is :
> Traceback (most recent call last):
>   File "", line 1, in ?
>   File "test.py", line 3, in aa
> b=b+1
> NameError: global name 'b' is not defined
> 
> Why this happens? Please do me a favor. 

The global statement makes a name global to a module, it doesn't make it 
global to the entire program. The function aa is in module test, the 
statements you entered in the shell are in a different module called 
__main__.

The particular form of import you used may also be confusing you: just 
because you imported '*' doesn't change the function: 'aa' was defined in 
the module 'test' and that is where it still looks for its global 
variables, all the import did was define a new name 'aa' in the __main__ 
module which refers to the same function object as 'aa' in 'test'.

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


Re: problem with global variable in a module

2006-11-25 Thread Diez B. Roggisch
hollowspook schrieb:
> def aa():
> global b
> b=b+1
> print b
> 
> b=1
> aa()
> 
> The above code runs well in python shell.
> 
> However I  have a problem as follows.
> 
> new a file named test.py
> 
> 
> def aa():
> global b
> b=b+1
> print b
> -
> 
> Then in python shell,
> 
> from test import *
> b=1
> aa()
> 
> The error message is :
> Traceback (most recent call last):
>   File "", line 1, in ?
>   File "test.py", line 3, in aa
> b=b+1
> NameError: global name 'b' is not defined
> 
> Why this happens? Please do me a favor. 

Because python does not know "real" globals - globals are always only
global on a module level. Now using the "from module import *"-syntax
asks for trouble. Because your global b above is global to the
__main__-module, not to the module test. But the aa-function expects it
to live in tests.

To make your example work, do it as this:

import test

test.b = 1
test.aa()


See
http://effbot.org/pyfaq/tutor-whats-the-difference-between-import-foo-and-from-foo-import.htm

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

Re: problem with global variable in a module

2006-11-25 Thread hollowspook
Thanks for all the replys.


"Diez B. Roggisch 写道:
"
> hollowspook schrieb:
> > def aa():
> > global b
> > b=b+1
> > print b
> >
> > b=1
> > aa()
> >
> > The above code runs well in python shell.
> >
> > However I  have a problem as follows.
> >
> > new a file named test.py
> > 
> >
> > def aa():
> > global b
> > b=b+1
> > print b
> > -
> >
> > Then in python shell,
> >
> > from test import *
> > b=1
> > aa()
> >
> > The error message is :
> > Traceback (most recent call last):
> >   File "", line 1, in ?
> >   File "test.py", line 3, in aa
> > b=b+1
> > NameError: global name 'b' is not defined
> >
> > Why this happens? Please do me a favor.
>
> Because python does not know "real" globals - globals are always only
> global on a module level. Now using the "from module import *"-syntax
> asks for trouble. Because your global b above is global to the
> __main__-module, not to the module test. But the aa-function expects it
> to live in tests.
>
> To make your example work, do it as this:
>
> import test
>
> test.b = 1
> test.aa()
>
>
> See
> http://effbot.org/pyfaq/tutor-whats-the-difference-between-import-foo-and-from-foo-import.htm
> 
> Diez

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