'Scope' can be defined as the accessibility of a variable.
Say for example, in every office, there is a restricted area where only a few people have access.
Similarly, in Python, the variables also have some access restrictions. The variables that are defined inside a Function, cannot be accessed outside of it.
def func(): x = 5 func() print(x)
Now, the program execution starts from the third line.
And the Function 'func( )' is called.
And the function execution begins.
def func(): x = 5
And initialised the variable 'x' with '5' inside the function 'func( )'.
Then we come to the print statement,
And end up with an error as output,
This is because the variable 'x' is not accessable outside the Function. And that is called as 'Local Scope'.
The variables that are declared inside a Function, can only be accessed inside the Function and is local to that Function. That is called the 'Local Scope' of a variable.
Say for example, if there are two functions, 'first_func( )' and 'second_func( )'.
def first_func(): x = 5 print("The variable x is not accesible outside the first_func()") def second_func(): y = 7 print("The variable y is not accesible outside the second_func()") first_func() second_func()
So, we have declared two functions, 'first_func( )',
def first_func(): x = 5 print("The variable x is not accesible outside the first_func()")
And 'second_func( )'.
def second_func(): y = 7 print("The variable y is not accesible outside the second_func()")
And we have two variables, 'x' and 'y'.
While 'x' is declared inside the Function 'first_func( )' and is local to the 'first_func( )' and cannot be accessed outside it.
Similarly, 'y' is declared inside the Function 'second_func( )' and is local to the 'second_func( )' and cannot be accessed outside it.
Next, let us see the Local Scope in nested Function.
Nested Function is a Function inside an existing Function.
def outer_func(): x = 5 print("The variable x is accesible from the outer_func() and the value is ", x) def inner_func(): print("The variable x is accesible from the inner_func() and the value is ", x) inner_func() outer_func()
So, in the above example, there are two Functions, 'outer_func( )' and 'inner_func( )'. And the 'inner_func( )' resides inside the 'outer_func( )'.
Now, we have declared a variable 'x' inside the 'outer_func( )'.
def outer_func(): x = 5 print("The variable x is accesible from the outer_func() and the value is ", x) def inner_func(): print("The variable x is accesible from the inner_func() and the value is ", x) inner_func()
Now, since the 'inner_func( )' resides inside the 'outer_func( )'. The variable 'x' is also accessable inside the 'inner_func( )'.
Now, what if, the variable 'x' was defined inside the 'inner_func( )'. Can the variable 'x' be accessed from the 'outer_func( )'?
Well! The answer is no.
Let us see the above example.
def outer_func(): print("The variable x is not accesible from the outer_func()") def inner_func(): x = 5 print("The variable x is accesible from the inner_func() and the value is ", x) inner_func() outer_func()
So, in the above code, we have declared the variable 'x' inside the 'inner_func( )'.
def outer_func(): print("The variable x is not accesible from the outer_func()") def inner_func(): x = 5 print("The variable x is accesible from the inner_func() and the value is ", x) inner_func()
So, the variable 'x' is not accesible from the 'outer_func( )'.
So, the moral of the story is, the variable that is declared at a higher scope could be accessed at a lower scope.
Say for example, your Boss will have access to your details. But you will not have access to any of your Boss's details.
And with this we come to the concept of 'Global Scope'.
The variables that are declared outside the Function are accessable inside a Function. And they are said to be in 'Global Scope'.
Let us see in the below example :
x = 5 def func(): print("Inside the function ",x) func() print("Outside the function ",x)
So, in the above example, we have declared a variable 'x', outside the Function and initialised with '5'.
Now since, the variable 'x' is declared outside the Function, it is accessible both inside and outside the Function.
Now, we were able to access the variable 'x' inside the Function. But what if, we wanted to change/modify the value of 'x'.
x = 5 def func(): x = 8 print("Inside the function ",x) func() print("Outside the function ",x)
In the above code, we get a strange output. Let us see how?
The program execution starts by initialising the global variable 'x' with the value '5'.
Then we come to the next line where Function 'func( )' is called
And the Function 'func( )' execution begins,
def func(): x = 8 print("Inside the function ",x)
In the first line of the Function 'func( )'. The value of 'x' is initialised with '8'.
Now, this is time to pause and note something very IMPORTANT. i.e. If a variable is declared inside a Function. Then it is treated as a different variable.
In this case, since the value of 'x' is initialised with '8'. It is treated as a redefinition.
And 'x' is a new variable altogether.
That is the reason why, the print statement inside the Function 'func( )',
Prints the value '8'. i.e. The value of the above variable in the local scope.
Then the control comes out of the Function 'func( )' and the next print statement,
Prints the value of the global variable i.e. '5'.
So, the moral of the story is, there are two different variables with the same name 'x'.
Let us look at another example,
x = 5 def func(): x = x + 6 print("Inside the function ",x) func() print("Outside the function ",x)
And we end up with the below error.
Any guesses why?
Let's investigate.
The error occurred with the statement,
Which is inside the Function 'func( )'.
Now since, there is this assignment operator (i.e. '=') in 'x = x + 6', the variable 'x' is treated as a new variable declaration.
Although, the variable 'x' is defined with the initial value '5'.
But that is declared in 'Global Scope'.
So, we end up with the error,
Now, to resolve the above problem, 'global' keyword comes for rescue.
So, in the above example we have seen that if we wanted to make any changes to a variable inside the Function. It would be treated as a Local Variable for that Function.
With the help of 'global' keyword, we can get rid of that.
Let us see in the below example.
x = 5 def func(): global x x = x + 6 print("Inside the function ",x) func() print("Outside the function ",x)
And we got rid of the error with the 'global' keyword.
All we have done is, inside the Function 'func( )',
def func(): global x x = x + 6 print("Inside the function ",x)
We have declared the variable 'x' with the keyword 'global'.
And 'x' is the global variable now. In other words, we have converted the local variable to a global variable using the 'global' keyword.
Next, let us see, how the 'global' keyword can be used in nested Functions?
def outer_func(): x = 5 def inner_func(): global x x = 9 print("Before calling inner_func the value of x is ", x) inner_func() print("After calling inner_func the value of x is ", x) outer_func() print("Value of x outside the function ", x)
So, in the above code, we have declared two functions :
The 'inner_func( )' is inside the 'outer_func( )'.
Now, in the 'outer_func( )', we have declared a local variable 'x'
Inside the 'outer_func( )'.
def outer_func(): x = 5 def inner_func(): global x x = 9
Now, to access the same local variable 'x' inside the 'inner_func( )',
def inner_func(): global x x = 9
We tried the 'global' keyword before 'x'.
And initialised it with '9'.
But the problem with this approach is, this 'x' with 'x = 9' becomes a global variable. i.e. This 'x' is not the same local variable 'x' in 'outer_func( )'.
So, 'x = 9' becomes a global variable and 'x = 5' is a local variable that is local to 'outer_func( )'.
And we end up with two variables again.
To overcome this problem, there is another keyword called 'nonlocal'.
Let us rewrite the above example with 'nonlocal' keywotd.
def outer_func(): x = 5 def inner_func(): nonlocal x x = 9 print("Before calling inner_func the value of x is ", x) inner_func() print("After calling inner_func the value of x is ", x) outer_func()
Now, the above problem is solved after using the 'nonlocal' keyword,
So, the local variable 'x' inside the 'outer_func( )',
Is same as the local variable 'x' inside the 'inner_func( )'.