Local, Non Local and Global Variables Scope in Python

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

>>> x = 26  # Global Variable
>>> def mybar():
...     x = 35  # Local Variable to function
...     print(x)
...     x+=1
...
>>> mybar()
35
>>> mybar()
35
>>> x
26
>>> x
26

When you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in mybar assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.

>>> x = 26  # Global Variable
>>> def mybar():
...     print(x)
...     x+=1
...
>>> mybar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in mybar
UnboundLocalError: local variable 'x' referenced before assignment
>>> x
26

>>> x = 10
>>> def foo():
...     print(x)
...     x = 26
...     print(x)
...
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'x' referenced before assignment

You can access the outer scope variable by declaring it global

>>> x = 26
>>> def mybar():
...     global x  # Referring Global Variable here
...     print(x)
...     x+=1
...
>>> mybar()
26
>>> x
27
>>> x
27
>>> mybar()
27
>>> x
28
>>> x = 26
>>> def mybar():
...     global y
...     print(y)
...     y+=1
...
>>> mybar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in mybar
NameError: name 'y' is not defined
>>> x
26
>>> x
26
>>> y = 10
>>> mybar()
10
>>> y
11
>>> mybar()
11
>>> y
12
>>> mybar()
12
>>> mybar()
13
>>>

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals.

>>> x = 40   # Global Scope
>>> def foo():
...     x = 28    # Enclosed Scope
...     def bar():
...             nonlocal x
...             print(x)
...             x+=1
...     bar()
...     print(x)
...
>>> foo()
28
29

# Below program gives error
>>> x = 10
>>> def foo():
...     nonlocal x
...     print(x)
...     x =26
...     print(x)
...
  File "<stdin>", line 2
SyntaxError: no binding for nonlocal 'x' found

Sharing Global Variables across modules

To share information across modules within a single program is to create a special module often called config or cfg. Import the config module in all modules of your application; the module then becomes available as a global name. As there is only one instance of each module, any changes made to the module object get reflected everywhere in the project.

config.py

name = 'Girish'

mymodule.py

import config
print(config.name)
C:\Users\Girish>python mymodule.py
Girish

mynewmodule.py

import config
print(config.name)
C:\Users\Girish>python mynewmodule.py
Girish

Now try updating the config.py with name = 'Python' and execute those two files, now you can see the updated value for those two modules.

C:\Users\Girish>python mynewmodule.py
Python

C:\Users\Girish>python mymodule.py
Python

References

  • https://docs.python.org/2/faq/programming.html
  • https://docs.python.org/3/reference/simple_stmts.html#the-global-statement
  • https://docs.python.org/3/reference/simple_stmts.html#nonlocal

Learn about more features of Python in our upcoming blog articles.

Happy Learning!