global variable warning in python

Question:

I have a python 2.6 script (yes I know I should upgrade to at least 2.7) that looks like this:

ret_code = 0

def some_func()
  global ret_code
  ...

if __name__ == '__main__':
  global ret_code
  ...

Now I get a warning if I run the code:
*SyntaxWarning: name ‘ret_code’ is assigned to before global declaration global ret_code*

Why do I get this warning?

I can solve the problem by doing so:

def some_func()
      global ret_code
      ...

if __name__ == '__main__':
  global ret_code
  ret_code = 0 #assign 0 here instead of above
  ...

Still that doesn’t answer my question. What is wrong with the original code?

Asked By: whomaniac

||

Answers:

The best direct way to fix this is to remove the global declaration from underneath if __name__ == '__main__':. You don’t need it there. Unlike some other languages, an if statement doesn’t introduce a new scope in Python – any variables you assign in that block are global, just as they would be without the if there.

This also explains why it is an error: to declare a variable as global, you are not allowed to have used that variable name previously in the same scope (presumably because it would be confusing for the global statement to make assignments before it go to the global variable, and Python doesn’t support the same name being both global and local in the same scope). Since the if doesn’t introduce a new scope, the first assignment to ret_code is in the same scope as the global declaration under the if; but the global declaration comes later than the assignment, which isn’t allowed.

For an even better fix, consider if you can remove the mutable global state from your program entirely, since it usually causes more problems than its worth somewhere down the track. Here, it seems likely that you’re using ret_code as a program exit code – ie, you’ll be doing sys.exit(ret_code) somewhere – but you’re deciding inside a function which exit code to use. Instead, pass enough information back out to the top level code for it to decide which exit code to use.

Answered By: lvc