A Python Tutorial To Understanding Scopes and Closures.

codes provided in this guide are in python but can be extrapolated to other languages.

LEXING / TOKENIZING.

b = 6
def f1(a):
print(a)
print(b)
from dis import dis
dis(f1)
2 0 LOAD_GLOBAL 0 (print) *1
2 LOAD_FAST 0 (a) *2
4 CALL_FUNCTION 1 (1 positional, 0 keyword) *3
6 POP_TOP
3 8 LOAD_GLOBAL 0 (print)
10 LOAD_GLOBAL 1 (b) *4
12 CALL_FUNCTION 1 (1 positional, 0 keyword)
14 POP_TOP
16 LOAD_CONST 0 (None) *5
18 RETURN_VALUE
*1. Load global name print.
*2. Load local name a.
*3. Call print function with 1 positional argument.
*4.
Load global name b.
*5. Load constant, in which case there None.
def f1(a):
print(a)
print(b)

def f2():
c = a + b
return c * 3

return f2()
2           0 LOAD_GLOBAL              0 (print)
2 LOAD_DEREF 0 (a)
4 CALL_FUNCTION 1
6 POP_TOP
3 8 LOAD_GLOBAL 0 (print)
10 LOAD_GLOBAL 1 (b)
12 CALL_FUNCTION 1
14 POP_TOP
4 16 LOAD_CLOSURE 0 (a)
18 BUILD_TUPLE 1
20 LOAD_CONST 1 (<code object f2 at 0x10d966930, file "<ipython-input-7-e2aa7fecf82d>", line 4>)
22 LOAD_CONST 2 ('f1.<locals>.f2')
24 MAKE_FUNCTION 8
26 STORE_FAST 1 (f2)
7 28 LOAD_FAST 1 (f2)
30 CALL_FUNCTION 0
32 RETURN_VALUE

Lexical scoping (sometimes known as static scoping ) is a convention used with many programming languages that sets the scope (range of functionality) of a variable so that it may only be called (referenced) from within the block of code in which it is defined.

scopes can be nested inside another.

VARIABLE LOOK-UPS.

EXPLAINING SECOND DISASSEMBLED CODE AND CLOSURES.

b = 6def f1(a):
print(a)
print(b)
def f2():
c = a + b
return c * 3
return f2 // return an unexecuted version of f2f2 = f1(10) // prints 10 and 6
c = f2()
print(c) // prints 48

f2() still has a reference to that scope, and that reference is called closure.

the idea of closure being loaded during lexing is the major point of this image.

… python is very different in a way:

a = 5
def function():
print(a)
a = 10
function() // raises the error below.
UnboundLocalError. Traceback (most recent call last)
<ipython-input-6-2fcbbbc1fe81> in <module>()
----> 1 function()
<ipython-input-5-8e223d9813d8> in function()
1 a = 5
2 def function():
----> 3 print(a)
4 a = 10
5
UnboundLocalError: local variable 'a' referenced before assignment
a = 5
def function():
global a
print(a)
a = 10
function() // prints 5
def f1():
a = 1
b = 2
def f2():
a += b
return a
return f2()f1() // raises an error
UnboundLocalError Traceback (most recent call last)
<ipython-input-7-2e4e4113319b> in f2()
3 b = 2
4 def f2():
----> 5 a += b
6 return a
7 return f2()
UnboundLocalError: local variable 'a' referenced before assignment
def f1():
a = 1
b = 2
def f2():
nonlocal a
a += b
return a
return f2()print(f1()) // prints 3

--

--

--

A little bit of this. A little bit of that.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to Add One-Click Gmail Login to Your WordPress Website

The Google Apps login banner.

[Python learning journal] Day 1

How do Git and Github work together?

Starting with Git? Here is your go-to guide.

Git Cheatsheet

Dynamically direct routes for polymorphic associations

Hadooping: Hive

Bullet Proofing Django Models

Why Google Built Spanner

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Danny Mcwaves

Danny Mcwaves

A little bit of this. A little bit of that.

More from Medium

Making Multilingual Subtitles using Machine Translation, Aegisub, Notepad++, and Python

GitHub OAuth using Python and Flask

Your first simple Encryption Algorithm

How to reverse integer using modulus operator(Python)