Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global variables confusion in python

I have a global variables that I am using as a default variable. Depending on what happens in my program I need the ability to change those defaults and have the changes persist through the remaining operation of my code. I want them changed and defined everywhere hence I used a global variable. Here is some test code that shows how I am trying to modify these variables.

When I do this I have the following problems...

  1. The program thinks that myGlobal hasn't been defined in main. But it has. Why?
  2. When i call a subroutine after I have changed myGlobal. I didn't want that to happen.

What is the proper way to accomplish what I am trying to do here? Examples?

#!/usr/bin/python

import sys

myGlobal = "foo"

print "********************"
print "MyGlobal %s" % myGlobal
print "********************"


def main(argv):

   #UnboundLocalError: local variable 'myGlobal' referenced before assignment
   print '1. Printing the global again: ' + myGlobal

   myGlobal = "bar"
   print "2. Change the global and print again: " + myGlobal

   # now call a subroutine
   mySub()

# Checks for output file, if it doesn't exist creates one
def mySub():
   # Why isn't the global "bar" not "foo"?
   print '3. Printing the global again: ' + myGlobal

   myGlobal = "black sheep"
   print "4. Change the global and print again: " + myGlobal




if __name__ == "__main__":
   main(sys.argv[1:])
like image 802
codingJoe Avatar asked Mar 30 '12 03:03

codingJoe


2 Answers

If you want to assign to, rather than read a module-global variable from within a function, you need the global keyword:

def main(argv):
  global myGlobal
  #...
  myGlobal = "bar"

Otherwise the assignment will just create a new local variable that shadows your global variable (so changes to it will not affect the global variable, like it is the case in your example).

That said, you could also use a class here to have your functions share state in a nicer way:

class MyApp(object):
  def main(self, argv):
    self.myVar = "bar"
    self.mySub()

  def mySub(self):
    print self.myVar

MyApp().main(sys.argv[1:])
like image 80
Niklas B. Avatar answered Sep 24 '22 03:09

Niklas B.


What you are looking for is the global statement in python. Insert global myGlobal before your codeblocks in main and mySub and there you have a predictable behavior. Having said that, if you have to pass state information between functions, use arguments to the function. That's much neater.

like image 38
Senthil Kumaran Avatar answered Sep 23 '22 03:09

Senthil Kumaran