You need to learn about "scope". The scope rules of Python tell you all about who can see a variable based on where it is assigned.
Variable scope is defined as Local, Enclosed, Global or Built-in. Built-in is a special scope for all the standard Python libraries. This lets you use functions and variables from the standard libraries without having to import anything. Global is for anything defined in a file (module) but not inside of a function. Local is for variables defined inside of a function. Enclosed is something most people don't use.
There is a "precedence" of scope. The Local scope can see variables defined in the Enclosed, Global scope and Built-in Scope. Enclosed scope can see variables defined in Global and Built-in scopes. Global can see variables defined in the Built-in scope. You will sometimes see this scope order of precedence referred to as LEGB.
abc = ['a', 'b', 'c'] # This is in the Global scope
def func():
abc[0] = 'A' # This is Local socpe, but it can see abc defined in Global scope
print(len(abc)) # Print and len are defined in the built-in scope. Also visible here
c = abc[2] # This variable is defined in the local scope. Cannot be seen outside this func()
def other_func():
print(c) # c is not defined in this scope. Will raise an exception
Python does have a cheat to get around the local scope restriction. If you declare a local variable to be "global", Python assigns the variable in the global scope.
abc = ['a', 'b', 'c'] # This is in the Global scope
c = None
def func():
global c # Tells Python to use "c" from the global scope
c = abc[2] # Sets the global variable c
def other_func():
print(c) # Do not need global here since there is no variable assignment
other_func()
func()
other_func()
Output:
None
c
The "global" keyword should be used sparingly if at all. Code that makes extensive use of global variables is difficult to debug. It is very easy to forget to use the "global" declaration and accidentally assign a to a local variable, and it is difficult to find all the places a global variable might be changed.
Instead of using lots of global variables you should write your functions to accept arguments and return values.
abc = ['a', 'b', 'c'] # This is in the Global scope
def func():
return abc[2]
def other_func(arg):
print(arg)
other_func(func())
Output:
c