Problem with global variables
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
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
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
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
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
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
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
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
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
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
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
"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
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
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