tags:

views:

49

answers:

2

Hey all again.

It appears to me that functions can reference variables outside of their scope but cannot set them. Is this correct? Am I understanding this right. I also included the gloals usage,. I KNOW they are bad - ju-ju and will avoid.

I know how to get around this but just want to be clear.

My example program:

import foo

# beginning of functions

# this one works because I look at the variable but dont modify it
def do_something_working:

    if flag_to_do_something:
          print "I did it"

# this one does not work because I modify the var
def do_something_not_working:

    if flag_to_do_something:
          print "I did it"
          flag_to_do_something = 0

# this one works but if I do this god kills a kitten
def do_something_using_globals_working_bad_ju_ju:

    global flag_to_do_something

    if flag_to_do_something:
         print "I did it"
         flag_to_do_something = 0


# end of functions

flag_to_do_something = 1

do_something_working()
do_something_not_working()
do_something_using_globals_working_bad_ju_ju()
A: 

Yep, pretty much. Note that "global" variables in Python are actually module-level variables - their scope is that Python module (a.k.a. source file), not the entire program, as would be the case with a true global variable. So Python globals aren't quite as bad as globals in, say, C. But it's still preferable to avoid them.

David Zaslavsky
+5  A: 

Correct. Well mostly. When you flag_to_do_something = 0 you are not modifying the variable, you are creating a new variable. The flag_to_do_something that is created in the function will be a separate link to (in this case) the same object. However, if you had used a function or operator that modified the variable in place, then the code would have worked.

Example:

g = [1,2,3]
def a():
    g = [1,2]
a()
print g #outputs [1,2,3]

g = [1,2,3]
def b():
    g.remove(3)
b()
print g #outputs [1,2]
Blue Peppers
Ahhh I see. So is there something like remove for non list variables ? Like flag_to_do_something.set(0) ?
William T Wild
No, you can't mutate *variables* (which are just names), only *objects*. And immutable objects, like ints, can't be mutated. You can, however, assign to global variables by using the `global` declaration inside the function: `global flag_to_do_something; flag_to_do_something = 0`.
Thomas Wouters