Not all variables are accessible from all parts of our program, and not all variables exist for the same amount of time. Where a variable is accessible and how long it exists depend on how it is defined. We call the part of a program where a variable is accessible its scope, and the duration for which the variable exists its lifetime.
There are four main type scopes in python.
Note : It's important to note that scopes in Python do not correspond to the source code blocks as demarcated by indentation. For-loops, with-blocks, and the like do not introduce new nested scopes.
Those names defined inside the current function.
def fun():
i = 10 # local scope
print("i=", 10)
fun()
print(i) # this leads to error because i is local scope
Blocks will not create a new scope
def fun():
if(1):
i = 10 # still local scope there is no block scope in python
print("i=", 10)
fun()
Those names defined inside any and all enclosing functions
def outer():
i = 10
def inner():
i = 30 # This will create new local variable i instead of using outer i
print("inner i=", i)
inner()
print("Outer i=", i)
outer()
def outer():
i = 10
def inner():
nonlocal i
i = 30 #This will refer outer i
print("inner i=", i)
inner()
print("Outer i=", i)
outer()
def outer():
def inner():
i = 10
inner()
print("Outer i=", i) # this leads to error because variable in in inner function cannot be accessed out side
outer()
print("Outer i=", i) # this leads to error because variable in in inner function cannot be accessed out side
NameError: name 'i' is not defined
Those names defined at the top level of a module. Each module brings with it a new global scope. A variable which is defined in the main body of a file is called a global variable. It will be visible throughout the file, and also inside any file which imports that file. Global variables can have unintended consequences because of their wide-ranging effects – that is why we should almost never use them.
i = 10 # global scope
def fun1():
print("fun1 i=", i)
def fun2():
i = 20 # This will created a new local variable i
print("fun2 i=", i)
fun1()
fun2()
fun1()
i = 10 # global scope
def fun1():
print("fun1 i=", i)
def fun2():
global i # This will refer to global variable i
i = 20
print("fun2 i=", i)
fun1()
fun2()
fun1()
Those names built into the Python language through the special built-ins module
import sys
def print(x):
sys.stdout.write("logger message: "+str(99) + '\n')
print(10) # instead of buit in scope print. Global scope print is used
from custom_print import print
print(10) # instead of buit in scope print. Global scope print defined in custom_print module is used
a = 0
def fun1():
print("fun1: a=", a)
def fun2():
a = 10 # By default, the assignment statement creates variables in the local scope
print("fun2: a=", a)
def fun3():
global a # refer global variable
a = 5
print("fun3: a=", a)
fun1()
fun2()
fun1()
fun3()
fun1()
# This is a global variable
a = 0
if a == 0:
# This is still a global variable
b = 1
def my_function(c):
# this is a local variable
d = 3
print("c=", c)
print("d=", d)
print("a=", a)
print("b=", b)
# Now we call the function, passing the value 7 as the first and only parameter
my_function(7)
# a and b still exist
print("a=", a)
print("b=", b)
# c and d don't exist anymore -- these statements will give us name errors!
print(c)
print(d)