Python: Why does global “a” preserve its value without return statement after local assignment in a function in this code? | Sololearn: Learn to code for FREE!
New course! Every coder should learn Generative AI!
Try a free lesson
+ 1

Python: Why does global “a” preserve its value without return statement after local assignment in a function in this code?

a = [0] def func(x): x[0] = 1 func(a) print(a) # output: [1] If I change type “a” from list to integer then it outputs 0 (instead of 1). I’ve read about __closure__, perhaps this is the reason?

17th Jan 2020, 5:02 AM
Prof. Dr. Zoltán Vass
9 Answers
+ 3
Prof. Dr. Zoltán Vass if this was true than you should be able to change line 6 in Bilbo Baggins code and see the end result as the same result but... Try it yourself ... You can also see that by changing line 2 again result is... so once again...
17th Jan 2020, 1:48 PM
BroFar
BroFar - avatar
+ 2
Well, in your original code I do not see local variables which persist in a global context, but global variables which can be changed or cannot be changed in a local context. By the way, to create a closure (alias of enclave) we need 3 specific conditions: - We must have a nested function (function inside a function). - The nested function must refer to a value defined in the enclosing function. - The enclosing function must return the nested function. An example here: https://code.sololearn.com/cAHh20yp9Djq/?ref=app
17th Jan 2020, 1:46 PM
Bilbo Baggins
Bilbo Baggins - avatar
+ 2
That is correct Bilbo Baggins on the second code ... as Prof. Dr. Zoltán Vass was seeking.
17th Jan 2020, 1:53 PM
BroFar
BroFar - avatar
+ 2
"The first time that the function is called, Python creates a persistent object for the list or dictionary. Every subsequent time the function is called, Python uses that same persistent object that was created from the first call to the function.” https://docs.quantifiedcode.com/python-anti-patterns/correctness/mutable_default_value_as_argument.html
20th Jan 2020, 4:50 AM
Prof. Dr. Zoltán Vass
+ 1
thanks bro! BroFar
17th Jan 2020, 5:48 AM
Prof. Dr. Zoltán Vass
17th Jan 2020, 5:48 AM
BroFar
BroFar - avatar
+ 1
Well, it is not really a question of closures. The problem is that 'int' is immutable, and when you reassign it inside a function a new local variable is created (see func1 in the code below). On the other way, you can change a list without problems because it is a mutable object. func2() - without args - and func3() - using variable name as arg - are possible bypass. Read more here: https://stackoverflow.com/questions/15148496/passing-an-integer-by-reference-in-JUMP_LINK__&&__python__&&__JUMP_LINK https://code.sololearn.com/c4fk904147K5/?ref=app
17th Jan 2020, 8:49 AM
Bilbo Baggins
Bilbo Baggins - avatar
+ 1
Bilbo Baggins You’re absolutely right with the immutability of numbers. However, mutable objects (as eg lists) should also be discarded after exiting a function’s local scope. So we still need the concept of closure to explain how can a local variable persist in the global scope
17th Jan 2020, 1:33 PM
Prof. Dr. Zoltán Vass
0
yes as a = [0] it was never given any reason to change and yes as a closure: the following example from http://code.activestate.com/recipes/577760-change-a-functions-closure/ example: def g():     a = 1     def f():       print(a)     return f f1 = g()   f1()   # 1 x1 = inject_closure(f1, 2) x1() # 2 f1()   # 1
17th Jan 2020, 5:34 AM
BroFar
BroFar - avatar