Feb-06-2024, 02:00 PM
(This post was last modified: Feb-06-2024, 02:00 PM by deanhystad.)
Variables are "created" when Python code is parsed, not when it is executed. Before main() was ever called, the code for main "defined" a local vairable named "take_sum". You can see that if you look at the generated bytecode. Below I simplify the function to focus on the variable.
main() creates (take_sum) because line 6 does an assignment to the variable. (take_sum) is a local variable because main() does not declare it as global.
Notice how the code changes if we declare take_sum as global.
To fix your code, you could modify main() to always assign something to take_sum:
import dis def main(): if "take_sum" not in globals(): take_sum = 1 print(take_sum) print(dis.dis(main))
Output: 16 PRECALL 0
20 CALL 0
30 CONTAINS_OP 1
32 POP_JUMP_FORWARD_IF_FALSE 2 (to 38)
6 34 LOAD_CONST 2 (1)
36 STORE_FAST 0 (take_sum)
7 >> 38 LOAD_GLOBAL 3 (NULL + print)
50 LOAD_FAST 0 (take_sum)
52 PRECALL 1
56 CALL 1
66 POP_TOP
68 LOAD_CONST 0 (None)
70 RETURN_VALUE
Even if the comparison in line 5 (of the python code) causes execution to skip the assignment in line 6, main() still has a variable named (take_sum). It is part of the function's code.main() creates (take_sum) because line 6 does an assignment to the variable. (take_sum) is a local variable because main() does not declare it as global.
Notice how the code changes if we declare take_sum as global.
import dis def main(): global take_sum if "take_sum" not in globals(): take_sum = 1 print(take_sum) print(dis.dis(main))
Output: 4 0 RESUME 0
6 2 LOAD_CONST 1 ('take_sum')
4 LOAD_GLOBAL 1 (NULL + globals)
16 PRECALL 0
20 CALL 0
30 CONTAINS_OP 1
32 POP_JUMP_FORWARD_IF_FALSE 2 (to 38)
7 34 LOAD_CONST 2 (1)
36 STORE_GLOBAL 1 (take_sum)
8 >> 38 LOAD_GLOBAL 5 (NULL + print)
50 LOAD_GLOBAL 2 (take_sum)
62 PRECALL 1
66 CALL 1
76 POP_TOP
78 LOAD_CONST 0 (None)
80 RETURN_VALUE
Now main() uses STORE_GLOBAL and LOAD_GLOBAL when referencing (take_sum).To fix your code, you could modify main() to always assign something to take_sum:
def take_sum(a, b, c): return a+b+c def main(): if "take_sum" in globals(): take_sum = globals()["take_sum"] else: take_sum = lambda x,y,z: x+y+z print(take_sum) main()Or you could declare take_sum as global
def take_sum(a, b, c): return a+b+c def main(): global take_sum if "take_sum" not in globals(): take_sum = lambda x,y,z: x+y+z print(take_sum) main()