I started working in Python just recently and haven’t fully learned all the nuts and bolts of it, but recently I came across this post that explains why python has closures, in there, there is a sample code that goes like this:
y = 0
def foo():
x = [0]
def bar():
print x[0], y
def change(z):
global y
x[0] = y = z
change(1)
bar()
change(2)
bar()
change(3)
bar()
change(4)
bar()
foo()
1 1
2 2
3 3
and basically I don’t understand how it actually works, and what construct like x[0] does in this case, or actually I understand what it’s doing, I just don’t get how is it this 🙂
Before the
nonlocalkeyword was added in Python 3 (and still today, if you’re stuck on2.*for whatever reason), a nested function just couldn’t rebind a local barename of its outer function — because, normally, an assignment statement to a barename, such asx = 23, means thatxis a local name for the function containing that statement.globalexists (and has existed for a long time) to allow assignments to bind or rebind module-level barenames — but nothing (except fornonlocalin Python 3, as I said) to allow assignments to bind or rebind names in the outer function.The solution is of course very simple: since you cannot bind or rebind such a barename, use instead a name that is not bare — an indexing or an attribute of some object named in the outer function. Of course, said object must be of a type that lets you rebind an indexing (e.g., a list), or one that lets you bind or rebind an attribute (e.g., a function), and a list is normally the simplest and most direct approach for this.
xis exactly that list in this code sample — it exists only in order to let nested functionchangerebindx[0].