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!