Why Isn't the 'Global' Keyword Needed to Access a Global Variable

Why isn't the 'global' keyword needed to access a global variable?

The keyword global is only useful to change or create global variables in a local context, although creating global variables is seldom considered a good solution.

def bob():
me = "locally defined" # Defined only in local context
print(me)

bob()
print(me) # Asking for a global variable

The above will give you:

locally defined
Traceback (most recent call last):
File "file.py", line 9, in <module>
print(me)
NameError: name 'me' is not defined

While if you use the global statement, the variable will become available "outside" the scope of the function, effectively becoming a global variable.

def bob():
global me
me = "locally defined" # Defined locally but declared as global
print(me)

bob()
print(me) # Asking for a global variable

So the above code will give you:

locally defined
locally defined

In addition, due to the nature of python, you could also use global to declare functions, classes or other objects in a local context. Although I would advise against it since it causes nightmares if something goes wrong or needs debugging.

Why doesn't the with block in Python need the global keyword?

Python doesn't have block scopes. The with statement does not introduce a new scope; the body of the statement is still in the same scope that has the with statement.

Python has 4 kinds of scopes:

  1. The built-in scope, defining names available in any module without an explicit import.
  2. Global scopes, one per module.
  3. Non-local scopes
  4. Local scopes: defined by a function.

No other construct defines a new scope: not if statements, not for or while loops, not with statements, not try statements, not class statements. Only things that define new functions (def statements, lambda expressions, and comprehensions) create new (local) scopes.

Every name first looks in the local scope (which may be the global scope if not inside a function definition), then in any non-local scopes (which may not exist, if a function is defined in the global scope, not another local scope), then the global scope, and finally in the built-in scope.


A non-local scope is just a scope that isn't the current local scope. For a module defined at the global scope, the closest enclosing non-local scope is the global scope.

But if a function is defined inside another function, then the closest enclosing non-local scope is the local scope in which the function is defined.

Functions can be nested fairly deeply, so there could be 0 or more additional local scopes between the current local scope and the global scope in which name lookups can occur. For example,

x1 = 'a'

def f1():
x2 = 'b'
def f2():
x3 = 'c'
def f3():
x4 = 'd'
print(x1 + x2 + x3 + x4)
f3()
f2()

f1()

The output of this mess would be abcd. When the argument to the print statement requires values for each of the four variables, each lookup starts in the local scope. Only a value for x4 is found there; the other lookups extend into the nearest enclosing non-local scope, that of f2. A value for x3 is found there, so the lookup for x1 and x2 extend to the next non-local scope, that of f1. x2 is found, so f1 extends another stop. Finally, a value for x1 is found in the global scope.

So a non-local scope isn't so much a special kind of scope, just a name for a scope that isn't local to the currently executing function. It will either be the local scope of an enclosing function or the global scope.

Python unable to access global variable in simple grade program

In the getInput function, you declare that marks will be a global variable, but never actually assign it. Since the scope of the global keyword is only within that function, you actually never created a global variable marks.

Then in getGrades, you create another variable marks, which is local to getGrades, because you didn't declare marks as global in getGrades. This is why showGrades cannot find the variable marks; it is local to getGrades.

Try making declaring marks as a global inside of getGrades, and I'm pretty sure the problem will be fixed.

For more see: What are the rules for local and global variables in Python?


Edit: To confirm my thinking I decided to do an experiment: I created a function where I declared, but never assigned a global variable. We then run the function, and use the built in globals function to check if myglobalvariable actually exists in the global scope

>>> def globaltest():
global myglobalvariable

>>> globaltest()
>>> globals()

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'globaltest': <function globaltest at 0x0000027E24B11EA0>}

We see from the output above that, as expected, myglobalvariable is not in the global scope.

Python cannot read global variable in function even though I used global keyword

Use the class attribute instead:

class A:
def ___init__(self):
self.number_of_messages=0

def inc(self):
self.number_of_messages+=1
a = A()
print(a.inc())
print(a.number_of_messages)

but you can also:

number_of_messages = 0

class A():
def inc(self):
global number_of_messages
number_of_messages+=1

a = A()
a.inc()
print(number_of_messages)

you just forgot to declare the variable in the global scope

Global dictionaries don't need keyword global to modify them?

The reason is that the line

stringvar = "bar"

is ambiguous, it could be referring to a global variable, or it could be creating a new local variable called stringvar. In this case, Python defaults to assuming it is a local variable unless the global keyword has already been used.

However, the line

dictvar['key1'] += 1

Is entirely unambiguous. It can be referring only to the global variable dictvar, since dictvar must already exist for the statement not to throw an error.

This is not specific to dictionaries- the same is true for lists:

listvar = ["hello", "world"]

def listfoo():
listvar[0] = "goodbye"

or other kinds of objects:

class MyClass:
foo = 1
myclassvar = MyClass()

def myclassfoo():
myclassvar.foo = 2

It's true whenever a mutating operation is used rather than a rebinding one.

global keyword needed in the top-level declaration

No, there isn't. You need to use global inside a function if you want to set the value of a global variable in that function. You don't need to use global outside functions.

Why python need global keyword while C/C++ no need?

The fundamental difference is that C and C++ have variable declarations. The location of the declaration determines whether a global is declared.

In Python, you only have assignments. An assignment to a yet-unassigned variable creates that variable. An assignment to an existing variable changes that variable. Hence, without global you couldn't create a local variable if a global variable with that name existed.

For read-only usage do all global variables need to be explicitly imported into local scope?

There is no need to declare a global for a variable which you only read. In a complex program, this may help the reader; but there is no technical necessity. A more useful convention anyway is to use upper case for globals.



Related Topics



Leave a reply



Submit