Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
unbounded variable
#2
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.
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()
akbarza likes this post
Reply


Messages In This Thread
unbounded variable - by akbarza - Feb-06-2024, 12:34 PM
RE: unbounded variable - by deanhystad - Feb-06-2024, 02:00 PM
RE: unbounded variable - by akbarza - Feb-07-2024, 11:58 AM
RE: unbounded variable - by deanhystad - Feb-07-2024, 03:51 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020