Late python binding

I have a C ++ framework and learn some python.

Whist, I understand virtual functions for C ++, I, unfortunately, do not understand what is meant by late binding of closures in python.

Link: https://gist.github.com/deemson/8efabf56d67623ead804

Copy pasta from the tutorial:

functions = [] for n in [1, 2, 3]: def func(x): return n*x functions.append(func) # You would expect this to print [2, 4, 6] print( 'calling a list of bad closures and output is: {}' .format(str([function(2) for function in functions])) ) 

What exactly is going on here? When a function is added to the list, what values ​​does it have? Can someone please simplify this code so that I understand.

+5
source share
2 answers

Note that you can create functions at runtime that are more or less similar to lambdas in C ++. So basically you do iteration over the list, making n take values 1,2 and 3

 for n in [1, 2, 3]: def func(x): return n*x 

so each iteration you create a function called func that takes a value and multiplies it by n. By adding it to the list of functions, you save these functions so that you can iterate over the list for calling functions.

 [function(2) for function in functions] 

By doing this, you call each of the functions stored with a value of 2 , you expect this to output [2, 4, 6] ([1 * 2, 2 * 2, 3 * 2]), but instead returns [6, 6, 6] , WHY?, Because each function uses n for its calculations, so they really do not do 1*x, 2*x and 3*x , but actually n*x , and since x is bound for the last time to 3 , all functions perform 3*2 which becomes 6 .

Play around with the python console to check it correctly.

+1
source

In C ++, a function pointer is what is added to the list. After the cycle, for functions contains pointers to three different functions ( func(x) = n * x , func(x) = n * x and func(x) = n * x ). Note the dependency on n. As n changes, the behavior of these functions changes, and they are all equivalent.

In the second part of the code, the pointers are retrieved from the list, and each of the three functions is evaluated by argument 2 .

Here is another example to clarify. Imagine we are doing this:

 >>> functions [<function func at 0x0239AA70>, <function func at 0x0239AAB0>, <function func at 0x0239AB30>] >>> g = functions[2] >>> g <function func at 0x0239AB30> >>> g(10) 20 >>> g(100) 200 

What we see in the first lines is that functions contain pointers to three different functions. The next line extracts the third pointer from the list (which refers to func(x) = n * x ) and assigns it g. In fact, we defined the function g(x) = n * x with this call. Now we can evaluate g with arguments.

Note that since all functions depend on n , you can change n and the behavior will change.

 >>> n = 100 >>> g(10) 1000 
0
source

Source: https://habr.com/ru/post/1246593/


All Articles