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:
- The built-in scope, defining names available in any module without an explicit
import
. - Global scopes, one per module.
- Non-local scopes
- 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
What's the Easiest Way to Escape HTML in Python
Modifying List While Iterating
How to Find All Occurrences of a Substring
Does Python Have an Ordered Set
Why Does Concatenation of Dataframes Get Exponentially Slower
Find the First Instance of a Nonzero Number in a List in Python
Why Does the Division Get Rounded to an Integer
Why Do People Write #!/Usr/Bin/Env Python on the First Line of a Python Script
Getting Key With Maximum Value in Dictionary
Why Does On_Message Stop Commands from Working
How to Install Pygame on Python Via Pip (Windows 10)
How to Install Packages Offline
Why Is Nothing Drawn in Pygame At All
Download Large File in Python With Requests
Check If a Given Key Already Exists in a Dictionary
How to Select a HTML Element No Matter What Frame It Is in in Selenium
Get Statistics For Each Group (Such as Count, Mean, etc) Using Pandas Groupby