Advertisement
Tritonio

Notes on Python variable scope

Mar 15th, 2021
562
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.70 KB | None | 0 0
  1. Example 1: The difference between global and local variables
  2.  
  3. Global variables are accessible inside and outside of functions. Local variables are only accessible inside the function. In the example below, the function can access both the global and the local variable. However, trying to access the local variable outside the function produces an error.
  4.  
  5. global_var = 'foo'
  6. def ex1():
  7. local_var = 'bar'
  8. print global_var
  9. print local_var
  10.  
  11. ex1()
  12. print global_var
  13. print local_var # this gives an error
  14.  
  15. foo
  16. bar
  17. foo
  18. Traceback (most recent call last):
  19. File "nested_scope.py", line 12, in
  20. print local_var # this gives an error
  21. NameError: name 'local_var' is not defined
  22.  
  23. Example 2: How *not* to set a global variable
  24.  
  25. *Setting* a global variable from within a function is not as simple. If I set a variable in a function with the same name as a global variable, I am actually creating a new local variable. In the example below, var remains 'foo' even after the function is called.
  26.  
  27. var = 'foo'
  28. def ex2():
  29. var = 'bar'
  30. print 'inside the function var is ', var
  31.  
  32. ex2()
  33. print 'outside the function var is ', var
  34.  
  35. inside the function var is bar
  36. outside the function var is foo
  37.  
  38. Example 3: How to set a global variable
  39.  
  40. To set the global variable inside a function, I need to use the global statement. This declares the inner variable to have module scope. Now var remains 'bar' after the function is called.
  41.  
  42. var = 'foo'
  43. def ex3():
  44. global var
  45. var = 'bar'
  46. print 'inside the function var is ', var
  47.  
  48. ex3()
  49. print 'outside the function var is ', var
  50.  
  51. inside the function var is bar
  52. outside the function var is bar
  53.  
  54. Example 4: Nested functions
  55.  
  56. Scoping for nested functions works similarly. In the example below, the inner function can access both var_outer and var_inner. However, the outer function cannot access var_inner. Side note: the inner function is considered a closure if it makes reference to a non-global outside variable.
  57.  
  58. def ex4():
  59. var_outer = 'foo'
  60. def inner():
  61. var_inner = 'bar'
  62. print var_outer
  63. print var_inner
  64. inner()
  65. print var_outer
  66. print var_inner # this gives an error
  67.  
  68. ex4()
  69.  
  70. foo
  71. bar
  72. foo
  73. Traceback (most recent call last):
  74. File "nested_scope.py", line 53, in
  75. ex3()
  76. File "nested_scope.py", line 51, in ex3
  77. print var_inner # this gives an error
  78. NameError: global name 'var_inner' is not defined
  79.  
  80. Example 5: How *not* to set an outer variable
  81.  
  82. Like Example 2, setting a variable in the inner function creates a new local variable instead of modifying the outer variable. In the example below, var in the outer function does not get changed to 'bar'.
  83.  
  84. def ex5():
  85. var = 'foo'
  86. def inner():
  87. var = 'bar'
  88. print 'inside inner, var is ', var
  89. inner()
  90. print 'inside outer function, var is ', var
  91.  
  92. ex5()
  93.  
  94. inside inner, var is bar
  95. inside outer function, var is foo
  96.  
  97. Example 6: Another way to *not* set an outer variable
  98.  
  99. However, using the global keyword won't work in this case. global cause a variable to have module scope, but I want my variable to have the scope of the outer function. Per the Python 3000 Status Update, Python 3000 will have a nonlocal keyword to solve this problem. See PEP 3104 for more information about nonlocal and nested scopes. In the example below, var is still not changed to 'bar' in the outer function.
  100.  
  101. def ex6():
  102. var = 'foo'
  103. def inner():
  104. global var
  105. var = 'bar'
  106. print 'inside inner, var is ', var
  107. inner()
  108. print 'inside outer function, var is ', var
  109.  
  110. ex6()
  111.  
  112. inside inner, var is bar
  113. inside outer function, var is foo
  114.  
  115. Example 7: A workaround until Python 3000 arrives
  116.  
  117. A workaround is to create an empty class to use as an additional namespace. Now the variable in the outer function can be set to 'bar'.
  118.  
  119. class Namespace: pass
  120. def ex7():
  121. ns = Namespace()
  122. ns.var = 'foo'
  123. def inner():
  124. ns.var = 'bar'
  125. print 'inside inner, ns.var is ', ns.var
  126. inner()
  127. print 'inside outer function, ns.var is ', ns.var
  128. ex7()
  129.  
  130. inside inner, ns.var is bar
  131. inside outer function, ns.var is bar
  132.  
  133. Example 8: Alternative to Example 7
  134.  
  135. Update 2010-03-01: According to Alexander's comment below, this is not a good way to do things.
  136.  
  137. I learned about this method from Nihiliad's comment on my recursion example. To me, this seems like a more elegant alternative to the solution in Example 7.
  138.  
  139. def ex8():
  140. ex8.var = 'foo'
  141. def inner():
  142. ex8.var = 'bar'
  143. print 'inside inner, ex8.var is ', ex8.var
  144. inner()
  145. print 'inside outer function, ex8.var is ', ex8.var
  146. ex8()
  147.  
  148. inside inner, ex8.var is bar
  149. inside outer function, ex8.var is bar
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement