-1

I thought global variables inside a Python function had to be declared global. So why does the following compile and run without error?

#!/usr/bin/env python
text = "why is this seen?"
class Foo:
    def doit(self):
        print(text)
x = Foo()
x.doit()

I'd appreciate a citation to the Python3 manual if possible.

rocky
  • 7,226
  • 3
  • 33
  • 74
  • The global keyword is only *needed* when you are assigning to the global variable inside the function , but if you are assigning to it once, it becomes local variable (even if its used before assignment) . If you are not assigning to that, python will treat it as the global variable. – Anand S Kumar Jul 24 '15 at 15:38

3 Answers3

3

You asked for a reference to the Python 3 manual. I've bolded the section that says you don't need to use the global keyword to reference free variables.

https://docs.python.org/3/reference/simple_stmts.html?highlight=global#grammar-token-global_stmt

7.12. The global statement

global_stmt ::= "global" identifier ("," identifier)*

The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. It would be impossible to assign to a global variable without global, although free variables may refer to globals without being declared global.

Note that in most code all of the classes and functions that you reference are globals (or builtins) but you didn't think twice about not needing global print before calling it.

Duncan
  • 92,073
  • 11
  • 122
  • 156
1

Its all about scope, since text is declared outside, free from any class or function, it can be reached from anywhere. To get a better idea, consider these two examples:

#!/usr/bin/env python
text = "why is this seen?"
class Foo:
    def doit(self):
        text = "this is changed"
        print(text)

x = Foo()
x.doit()
print text

In the above example, we overwrite the text variable locally, in the Foo, class, but the global instance of text is the same. But in this instance:

#!/usr/bin/env python
text = "why is this seen?"
class Foo:
    def doit(self):
        global text
        text = "this is changed"
        print(text)

x = Foo()
x.doit()
print text

We declare that we want the global version of text and then we can modify it.

BUT: global variables are frowned upon, consider using input arguments to functions and returning new values instead of having variable globally accessible everywhere

The right way to do it:

#!/usr/bin/env python

class Foo:
    text = "why is this seen?"
    def doit(self):
        print(self.text)

x = Foo()
x.doit()

Have text encapsulated in the class!

heinst
  • 8,520
  • 7
  • 41
  • 77
  • 1
    To add to this, the `global` keyword only needs to be used to __change__ the global variable outside of the current scope – muddyfish Jul 24 '15 at 15:34
  • @muddyfish thanks for the addition :D – heinst Jul 24 '15 at 15:35
  • 2
    @muddyfish To add to adding to this, it's considered very unpythonic to use `global`. Your first attempt should be to use `return` values, using global only when necessary. – SuperBiasedMan Jul 24 '15 at 15:36
  • @SuperBiasedMan Isn't the purpose of stackoverflow to educate people on how to do things first and then if they should do those things secondarily? – muddyfish Jul 24 '15 at 15:37
  • @muddyfish Certainly, that's why I'm not suggesting your answer is wrong. I'm just adding more info. – SuperBiasedMan Jul 24 '15 at 15:38
0

You don't need to specify a variable using global if you just need to access it. You can do that without a global.

Here, Python will look in the class Foo scope first for the text variable. Since, it does not find the variable text in the Foo class so it will look into outer scope. Now, it finds the variable text, so it uses that value to print the output.

According to Python docs, at any time during execution, there are at least three nested scopes whose namespaces are directly accessible:

  1. the innermost scope, which is searched first, contains the local names
  2. the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
  3. the next-to-last scope contains the current module’s global names
  4. the outermost scope (searched last) is the namespace containing built-in names
Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126