Week 2 Blog Post - 27/06/2022
For the second week of the GSoC 2022 and the second post, I think it would be nice to do a bit more of a blog post on a python feature that I have been experimenting with this week, which is the nonlocal
statement.
Nonlocal
The nonlocal statement is a less well know feature in Python, which is used non-local, non-globally scoped variables. As described in the Python documentation:
The
nonlocal
statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope excluding globals. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.
While the use-cases are not plentiful, it can be used in nested functions, where you need to access a variable in the "parent" function from a nested "child" function within it. While this can be done using global
variables, giving local variables global scope may cause unwanted issues. The best way to illustrate the usage of the nonlocal statement is with an example:
def f():
x = 0
def increment_x():
x += 1
increment_x()
return x
print(f())
Running the above code, you will get the error, UnboundLocalError: local variable 'x' referenced before assignment.
This is where the nonlocal statement can be used. By modifying the above code using the nonlocal statement, we have
def f():
x = 0
def increment_x():
nonlocal x
x += 1
increment_x()
return x
print(f())
and the program now works as we would like it to.
Why use the nonlocal statement
In my project of creating a visualizer for PyElastica simulations, we use a visualization library. When updating the visualization, a function is called between each frame to run the code to calculate what the next frame should be visualizaing (in our case it is used to update the new position of the simulation objects in that frame). Now if the main code for the visualization is in the global scope of the python file, ie. outside of any function and in the main body of the python script, then this update function works fine. But as we would like for the visualization code to be wrapped in a function to be imported by users of the library into their own scripts, we have to deal with scoping issues, which in this case can be sorted using the nonlocal statement.
It is unlikely that I will be using the nonlocal statement, as there are better ways of achieving what I want in this particular case, namely using classes. However, I thought it was an interesting, less-common Python feature that I myself was not too familiar with, and would make a nice topic for the blog post for this week.