First of all, this post does NOT answer my question or give me any guide to answer my question at all.
My question is about mechanism function resolving non-local variables.
Code
# code block 1 def func(): vals = [0, 0, 0] other_vals = [7, 8, 9] other = 12 def func1(): vals[1] += 1 print(vals) def func2(): vals[2] += 2 print vals return (func1, func2) f1, f2 = func() Try to run f1, f2:
>>> f1() [0, 1, 0] >>> f2 [0, 1, 2] This shows that the object previously referred by vals are shared by f1 and f2, and not garbage collected after execution of func.
Will objects referred by other_vals and other be garbage collected? I think so. But how does Python decide not to garbage collect vals?
Assumption 1
Python interpreter will resolve variable names within func1 and func2 to figure out references inside the function, and increase the reference count of [0, 0, 0] by 1 preventing it from garbage collection after the func call.
But if I do
# code block 2 def outerfunc(): def innerfunc(): print(non_existent_variable) f = outerfunc() No error reported. Further more
# code block 3 def my_func(): print(yet_to_define) yet_to_define = "hello" works.
Assumption 2 Variable names are resolved dynamically at run time. This makes observations in code block 2 and 3 easy to explain, but how did the interpreter know it need to increase reference count of [0, 0, 0] in code block 1?
Which assumption is correct?
valsin the returned function objectsfunc1andfunc2, and that ref preventsvalsfrom being garbage collected. See What exactly is contained within a obj.__closure__?. In your 2nd examplenon_existent_variableis presumably a global, and you will get an error if you don't define it before callingf.