Can someone explain this bit of Python code?

I started working in Python recently and didnโ€™t fully study all the nuts and bolts, but recently I came across this post which explains why python has closures, there is an example code that looks 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 this actually works, and what kind of construct, for example x [0], in this case, or actually I understand what it does, I just donโ€™t understand how this happens :)

+4
source share
4 answers

Before the nonlocal keyword was added in Python 3 (to this day, if you were stuck on 2.* for any reason), the nested function simply could not repeat the binding of the local barename of its external function - because, as a rule , the assignment operator in barename, for example x = 23 , means that x is the local name for the function containing this operator. global exists (and has existed for a long time) to allow assignments to bind or rearrange file names at the module level, but nothing (except nonlocal in Python 3, as I said) to assign bindings or rename names in an external function.

The solution, of course, is very simple: since you cannot bind or reconfirm such a name, use the non- guest name instead - the index or attribute of some object named in an external function. Of course, the specified object must have a type that allows you to double-check indexing (for example, a list) or one that allows you to bind or restore an attribute (for example, a function), and the list is usually the simplest and most direct approach to this. x is exactly that list in this code example - it exists only to enable the nested function change rebind x[0] .

+8
source

It might be easier to understand if you look at this simplified code, where I deleted the global variable:

 def foo(): x = [0] def bar(): print x[0] def change(z): x[0] = z change(1) bar() foo() 

The first line in foo creates a single-item list. Then bar defined as a function that prints the first element in x , and the change function changes the first element of the list. When change(1) is called, the value of x becomes [1] .

+5
source

This code tries to explain when python creates a new variable, and when python reuses an existing variable. I rewrote the above code a bit to make it more understandable.

 y = "lion" def foo(): x = ["tiger"] w = "bear" def bar(): print y, x[0], w def change(z): global y x[0] = z y = z w = z bar() change("zap") bar() foo() 

This will produce this conclusion:

 lion tiger bear zap zap bear 

The fact is that the internal function change can affect the variable y and the elements of the array x , but this does not change w (because it gets its own local variable w , which is not shared).

+4
source

x = [0] creates a new list with a value of 0 in it. x [0] refers to the null-eth element in the list, which also turns out to be zero.

This example provides links to locks or skipped blocks of code within code.

+2
source

All Articles