nonlocal

    
      
diff --git a/pythonetc/README.md b/pythonetc/README.md
index f301925..c675167 100644
--- a/pythonetc/README.md
+++ b/pythonetc/README.md
@@ -77,6 +77,7 @@ More:
 1. ./str-append.md              (29 December 2020, 18:00)
 1. ./new-year.md                (31 December 2020, 18:00)
 1. ./scopes.md
+1. ./nonlocal.md
 1. ./str-concat.md
 1. ./bytearray.md
 1. ./join-lists.md
diff --git a/pythonetc/nonlocal.md b/pythonetc/nonlocal.md
new file mode 100644
index 0000000..94e7f25
--- /dev/null
+++ b/pythonetc/nonlocal.md
@@ -0,0 +1,67 @@
+
+Any enclosing variable can be shadowed in the local scope without affecting the global one:
+
+```python
+v = 'global'
+def f():
+  v = 'local'
+  print(f'f {v=}')
+f()
+# f v='local'
+
+print(f'{v=}')
+# v='global'
+```
+
+And if you try to use a variable and then shadow it, the code will fail at runtime:
+
+```python
+v = 'global'
+def f():
+  print(v)
+  v = 'local'
+f()
+# UnboundLocalError: local variable 'v' referenced before assignment
+```
+
+If you want to re-define the global variable instead of locally shadowing it, it can be achieved using `global` and `nonlocal` statements:
+
+```python
+v = 'global'
+def f():
+  global v
+  v = 'local'
+  print(f'f {v=}')
+f()
+# f v='local'
+print(f'g {v=}')
+# g v='local'
+
+def f1():
+  v = 'non-local'
+  def f2():
+    nonlocal v
+    v = 'local'
+    print(f'f2 {v=}')
+  f2()
+  print(f'f1 {v=}')
+f1()
+# f2 v='local'
+# f1 v='local'
+```
+
+Also, `global` can be used to skip non-local definitions:
+
+```python
+v = 'global'
+def f1():
+    v = 'non-local'
+    def f2():
+        global v
+        print(f'f2 {v=}')
+    f2()
+f1()
+# f2 v='global'
+```
+
+To be said, using `global` and `nonlocal` considered a bad practice that complicates the code testing and usage. If you want a global state, think if it can be achieved in another way. If you desperately need a global state, consider using [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) which is a little bit better.