The Python enclosing scopes has a larger scope than the local scopes. The enclosing scope can enclose one or more local scopes. Note enclosing scopes have larger scopes than the local scopes but a smaller region of influence when compared to global scope.
Link :Python local scopes
The program below shows an example of a function having an enclosing scope.
&gt;&gt;&gt; def enclosedFunc(): #this function enclosed the localFunc() m=901 def localFunc(): #localFunc() region starts here lc=900 print( 'lc=',lc ) print( 'm'=,m ) #localFunc() region ends here localFunc() #Calls the localFunc() print( 'In enclosedFunc() m=',m ) print( '\n',lc ) &gt;&gt;&gt; enclosedFunc() lc=900 m=901 In enclosedFunc() m=901 Traceback (most recent call last): File &quot;&lt;pyshell#16&gt;&quot;, line 1, in &lt;module&gt; enclosedFunc() File &quot;&lt;pyshell#15&gt;&quot;, line 9, in enclosedFunc print( '\n',lc ) NameError: name 'lc' is not defined
Some points to note from the code above:
i)In the code above the ‘enclosedFunc()’ is said to have an enclosed scope over the local scope of ‘localFunc()’ function.
ii)When enclosedFunc() is called, it goes through the code of the localFunc() function. And inside the enclosedFunc() we have called the localFunc(), so that means the localFunc() code is executed first.
iii)Inside the localFunc() we could access the ‘m’ and ‘lc’ variable. But once the scope is outside the localFunc() we cannot access the ‘lc’ variable because it is available only under the localFunc() region, so in trying to access it we get the error message “Traceback… NameError: name ‘lc’ is not defined”.
Since enclosed scopes have influence over the local scope it does not mean the enclosed scopes variable will take over the local scope variable. In local scope, a local variable has more power over the other scopes variable. This means the local variable value will be always preferred in the local scope. Consider the example below.
&gt;&gt;&gt; def OuterFunc(): var=900 def InnerFunc(): #InnerFunc() region starts here*** var=12345 #same name as the outer variable print( var ) #InnerFunc() region ends here**** InnerFunc() #Calls the InnerFunc() print( var ) &gt;&gt;&gt; OuterFunc() 12345 900
Inside the InnerFunc() printing the ‘var’ value gives the local region value, not the enclosed ‘var'(900) value. So you see the local ‘var’ has more influence in the local region.
Outside the InnerFunc(), we tried to print the value of ‘var’ again, this time the enclosed scope variable value is printed out. This is obvious, as the local region variable has ceased to exist here, so the enclosed variable value is considered.
Link : Python global scopes
A function enclosing one or more functions
In case a function encloses one or more functions, then each function enclosed by the outer function will have their own local region. Note these local regions are not shared among them.
&gt;&gt;&gt; def OuterFunc(): out=901 def InnerFunc1(): #InnerFunc1() scope begins here out=123 print( &quot;Under InnerFunc1(), out=&quot;,out ) #InnerFUnc1() ends here def InnerFunc2(): #InnerFunc2() scope begins here var=789 print( &quot;\nUnder InnerFunc2(), out= &quot;,out ) #InnerFunc2() ends here def InnerFunc3(): #InnerFunc3() scope begins here var=77777 out=1000 print('\nUnder InnerFunc3(), var=',var ) print( 'Under InnerFunc3(), out=',out )#InnerFunc3() ends here InnerFunc1() InnerFunc2() InnerFunc3() print('Out=',out) &gt;&gt;&gt; OuterFunc() Under InnerFunc1(), out= 123 Under InnerFunc2(), out= 901 Under InnerFunc3(), var= 77777 Under InnerFunc3(), out= 1000 Out= 901
Under InnerFunc1(), the local ‘out’ value is taken, this is obvious as local variable has more power over other variables.
Under InnerFunc2(), the enclosed variable ‘out’ value is taken. This is due to the fact that the enclosed scope has still influence over the local scope.
Under InnerFunc3(), the value of ‘var’ is 77777, which is the local variable value. The value of the InnerFunc2() ‘var'(789) is not taken. The ‘out’ value in this case, is also the value of the local region not the enclosed one.
Function enclosing another enclosed function
When we have mulitple functions enclosing one another, the scope rule still applies. The local scope variable always have the higher influence. Next to the local scope is the scope enclosing the local scope. After this is the scope enclosing the inner two scopes and so on.
In the code below Outer1() encloses Outer2() which encloses Inner() function.
&gt;&gt;&gt; def Outer1(): var=65 def Outer2(): #Outer2 scope starts here var=90 m=101 def Inner(): #Inner() scope starts here m=111 print('Inner() m=',m) print('Inner() var=',var) #Inner() ends here Inner() print( '\nOuter2() var=',var ) #Outer2() ends here Outer2() print('Outer1() var=',var) &gt;&gt;&gt; Outer1() Inner() m= 111 Inner() var= 90 Outer2() var= 90 Outer1() var= 65
Inside Inner(), the local ‘m'(111) value is taken and not the one outside it. And here, the ‘var’ value taken is that of Outer2() and not that of the Outer1(). Since Outer2() scope is next to the Inner() scope.
Inside Outer2(), the ‘var'(90) is taken and not the Outer1() ‘var'(65). This is obviously because local variable has more power over the enclosing one.
And inside Outer1() the ‘var'(65) is taken, here the Outer2() ‘var’ has ceased to exist.
i)Any scopes not belonging to local scopes or global scopes are considered as enclosing scopes.
Always remember,the order followed by Python while looking for names in a scope or namespace is : local socpe> enclosing scope > global scope > built-in scope. This order is also known as ‘LEGB‘.
Link :Python scopes types