Python Forum
Trouble with global variables - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Trouble with global variables (/thread-3357.html)



Trouble with global variables - PickyBiker - May-17-2017

In the simple code below, schedule_last_update in the function check_schedule_file() is seen as a local variable and generates an error at line 15 claiming it is referenced before being assigned a value. It is assigned a value before the main() function. Why isn't that viewed as a global variable?

import os
schedule_file = "/home/pi/sprinkler/schedule.json"
schedule_last_update = os.path.getmtime(schedule_file)
schedule_current_update = schedule_last_update

def main():
  print(check_schedule_file())

def check_schedule_file():
  print("check_schedule_file")
  try:
    schedule_current_update = os.path.getmtime("/home/pi/sprinkler/schedule.json")
  except:
    print("check_schedule_file Error")
  if schedule_current_update != schedule_last_update:
    schedule_last_update = schedule_current_update
    print("schedule changed")
    return True
  return False

if __name__=="__main__":
  main()



RE: Trouble with global variables - sparkz_alot - May-17-2017

Line 22 "main()" is not indented.

You are calling  check_schedule_file() without any arguments. You should move your variables into the functions that need them and avoid trying to use globals.


RE: Trouble with global variables - PickyBiker - May-17-2017

I indented line 22, but the error still occurs. 

I agree that most times I should provide the arguments but occasionally, it's hard to do that. This is a case where that would be easy to do, but I still need to understand why what looks like it should be global, isn't.


RE: Trouble with global variables - snippsat - May-17-2017

(May-17-2017, 02:36 PM)PickyBiker Wrote: , but I still need to understand why what looks like it should be global, isn't.
It should look like this,4 space indent,argument given to function,no bare except.
import os

def check_schedule_file(schedule_file,schedule_last_update,schedule_current_update):
   print("check_schedule_file")
   try:
       schedule_current_update = os.path.getmtime('bar.json')
   except Exception as error:
       print(error)
   if schedule_current_update != schedule_last_update:
       schedule_last_update = schedule_current_update
       print("schedule changed")
       return True
   return False

if __name__ == "__main__":
   schedule_file = 'bar.json'
   schedule_last_update = os.path.getmtime(schedule_file)
   schedule_current_update = schedule_last_update
   check_schedule_file(schedule_file, schedule_last_update,schedule_current_update)
Now it's only one problem that it do not work.
Try to think of it,bar.json is just run 2 times every time code run,will always be equal.
You have to set start point and save to disk.
Then load getmtine vaule from disk to see if file has changed or not.


RE: Trouble with global variables - PickyBiker - May-17-2017

Thank you. I learned that placing the variables after the if __name__ == __"main"__: makes it clear they will be executed.  You also demonstrated how to send the arguments to the function.  I also learned that you can call any function you want following the if __name__ == __"main"__: it does not need to be main()

Am I to understand that there is no way to make a variable global?


RE: Trouble with global variables - buran - May-17-2017

(May-17-2017, 04:15 PM)PickyBiker Wrote: Am I to understand that there is no way to make a variable global?

no, that is not correct. In your code schedule_current_update and schedule_last_update are not considered global, because you try to change their value within the loop. That makes these names in the function local to the def and different from the 'global' ones. in order to be global, you need to add
global schedule_current_update
global schedule_last_update
at the top of the function body.

However, as snippsat and sparkz_alot advice you, that's bad programming practice. You should pass these as arguments to the function.


RE: Trouble with global variables - PickyBiker - May-17-2017

What a great place to learn. Now I understand the original issue with the variables not being global even though they appeared to be to me.

Please note that I did take seriously the idea of passing the arguments to the functions, I just could not stop wondering WHY those variables were not global. That is now clear up and I will pass the args in my script.

Thank you so much to all of you!


RE: Trouble with global variables - Larz60+ - May-17-2017

Python does indeed have globals, but ...

Global variables are considered bad programming in all languages by seasoned programmers.

Here's one reason that kills their use (In my book):
Coupling between various methods (or functions). Assume the following:
  • Method 1 sets global variable snoot to 4
  • Method 2, which uses the contents of snoot, executes method 3 as a thread if snoot equals 4
        Upon return from the thread, it checks the content of  snoot,
        if snoot equals anything other than 4, it prints message: 'method 3 was not executed'
        otherwise it prints message: ''method 3 was successfully executed'.
  • While the thread in method 2 was running, method 5 changed the global variable snoot to 2.
        Method2 will see the '2' when thread completes, thus prints the wrong message.
There are many other reasons you should avoid using globals , see: http://wiki.c2.com/?GlobalVariablesAreBad


RE: Trouble with global variables - buran - May-17-2017

Here is more, if you would like to read further https://docs.python.org/3.6/reference/executionmodel.html#naming-and-binding